Removal of old libg++.

This commit is contained in:
phil 1996-03-09 00:28:43 +00:00
parent 03548c36c3
commit 84a13b4cb6
42 changed files with 0 additions and 11325 deletions

View File

@ -1,177 +0,0 @@
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
This file is part of the GNU C++ Library. This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: values.h,v 1.4 1995/12/16 01:03:33 thorpej Exp $
*/
#ifndef _values_h
#define _values_h 1
#define BITSPERBYTE 8
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
#define CHARBITS BITS(char)
#define SHORTBITS BITS(short)
#define INTBITS BITS(int)
#define LONGBITS BITS(long)
#define PTRBITS BITS(char*)
#define DOUBLEBITS BITS(double)
#define FLOATBITS BITS(float)
#define MINSHORT ((short)(1 << (SHORTBITS - 1)))
#define MININT (1 << (INTBITS - 1))
#define MINLONG (1L << (LONGBITS - 1))
#define MAXSHORT ((short)~MINSHORT)
#define MAXINT (~MININT)
#define MAXLONG (~MINLONG)
#define HIBITS MINSHORT
#define HIBITL MINLONG
#if defined(sun) || defined(hp300) || defined(hpux) || defined(masscomp) || defined(sgi)
#ifdef masscomp
#define MAXDOUBLE \
({ \
double maxdouble_val; \
\
__asm ("fmove%.d #0x7fefffffffffffff,%0" /* Max double */ \
: "=f" (maxdouble_val) \
: /* no inputs */); \
maxdouble_val; \
})
#define MAXFLOAT ((float) 3.40e+38)
#else
#define MAXDOUBLE 1.79769313486231470e+308
#define MAXFLOAT ((float)3.40282346638528860e+38)
#endif
#define MINDOUBLE 4.94065645841246544e-324
#define MINFLOAT ((float)1.40129846432481707e-45)
#define _IEEE 1
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
#define FMINEXP (-(FMAXEXP + FSIGNIF - _HIDDENBIT - 3))
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
#elif defined(sony)
#define MAXDOUBLE 1.79769313486231470e+308
#define MAXFLOAT ((float)3.40282346638528860e+38)
#define MINDOUBLE 2.2250738585072010e-308
#define MINFLOAT ((float)1.17549435e-38)
#define _IEEE 1
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-(DMAXEXP + DSIGNIF - _HIDDENBIT - 3))
#define FMINEXP (-(FMAXEXP + FSIGNIF - _HIDDENBIT - 3))
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
#elif defined(sequent)
extern double _maxdouble, _mindouble;
extern float _maxfloat, _minfloat;
#define MAXDOUBLE _maxdouble
#define MAXFLOAT _maxfloat
#define MINDOUBLE _mindouble
#define MINFLOAT _minfloat
#define _IEEE 1
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-(DMAXEXP - 3))
#define FMINEXP (-(FMAXEXP - 3))
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
#elif defined(i386)
#define MAXDOUBLE 1.79769313486231570e+308
#define MAXFLOAT ((float)3.40282346638528860e+38)
#define MINDOUBLE 2.22507385850720140e-308
#define MINFLOAT ((float)1.17549435082228750e-38)
#define _IEEE 0
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-DMAXEXP)
#define FMINEXP (-FMAXEXP)
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
/* from Andrew Klossner <andrew%frip.wv.tek.com@relay.cs.net> */
#elif defined(m88k)
/* These are "good" guesses ...
I'll figure out the true mins and maxes later, at the time I find
out the mins and maxes that the compiler can tokenize. */
#define MAXDOUBLE 1.79769313486231e+308
#define MAXFLOAT ((float)3.40282346638528e+38)
#define MINDOUBLE 2.22507385850720e-308
#define MINFLOAT ((float)1.17549435082228e-38)
#define _IEEE 1
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (1-DMAXEXP)
#define FMINEXP (1-FMAXEXP)
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
#elif defined(convex)
#define MAXDOUBLE 8.9884656743115785e+306
#define MAXFLOAT ((float) 1.70141173e+38)
#define MINDOUBLE 5.5626846462680035e-308
#define MINFLOAT ((float) 2.93873588e-39)
#define _IEEE 0
#define _DEXPLEN 11
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-DMAXEXP)
#define FMINEXP (-FMAXEXP)
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
// #elif defined(vax)
// use vax versions by default -- they seem to be the most conservative
#else
#define MAXDOUBLE 1.701411834604692293e+38
#define MINDOUBLE (2.938735877055718770e-39)
#ifndef __NetBSD__ /* XXX */
#define MAXFLOAT 1.7014117331926443e+38
#endif /* ! __NetBSD__ */
#define MINFLOAT 2.9387358770557188e-39
#define _IEEE 0
#define _DEXPLEN 8
#define _FEXPLEN 8
#define _HIDDENBIT 1
#define DMINEXP (-DMAXEXP)
#define FMINEXP (-FMAXEXP)
#define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
#define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
#endif
#define DSIGNIF (DOUBLEBITS - _DEXPLEN + _HIDDENBIT - 1)
#define FSIGNIF (FLOATBITS - _FEXPLEN + _HIDDENBIT - 1)
#define DMAXPOWTWO ((double)(1L << LONGBITS -2)*(1L << DSIGNIF - LONGBITS +1))
#define FMAXPOWTWO ((float)(1L << FSIGNIF - 1))
#endif

View File

@ -1,13 +0,0 @@
# Makefile for g++ library genclass
PROG= genclass
SRCS= genclass.sh
NOMAN=
STRIP=
genclass: genclass.sh
sed -e 's|^PROTODIR=.*|PROTODIR=${DESTDIR}/usr/include/g++/gen|' \
-e 's|<VERSION>|2.4|' ${.ALLSRC} > ${.TARGET}
.include <bsd.prog.mk>
.include "../../../usr.bin/Makefile.inc"

View File

@ -1,452 +0,0 @@
#!/bin/sh
# Copyright (C) 1989 Free Software Foundation, Inc.
#
# genclass program enhanced by Wendell C. Baker
# (original by Doug Lea (dl@rocky.oswego.edu))
#This file is part of GNU libg++.
#GNU libg++ 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 1, or (at your option)
#any later version.
#GNU libg++ 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 GNU libg++; see the file COPYING. If not, write to
#the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#
# genclass -list [proto ...]
# genclass -catalog [proto ...]
# genclass type1 {ref|val} proto [out_prefix]
# genclass -2 type1 {ref|val} type2 {ref, val} proto [out_prefix]
#
# Generate classes from prototypes
#
name=genclass ;
usage="
$name -list [proto ...]
$name -catalog [proto ...]
$name type1 {ref|val} proto [out_prefix]
$name -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]" ;
case "$1" in
-usage)
#
# -usage
#
echo "usage: $usage" 1>&2 ;
exit 0;
;;
-version)
#
# -version
#
# <VERSION> is substituted by the build process.
# We currently use the libg++ version number (extracted from ../Makefile).
echo "$name: version <VERSION>" ;
exit 0;
;;
-requires)
#
# -requires
#
# The following line should contain any nonstandard programs
# which must be in the users's path (i.e. not referenced by a
# fullpath);it allows one to check a script for dependencies
# without exhaustively testing its usages.
# ... in this case genclass depends on nothing else.
echo ;
exit 0;
;;
esac ;
# pull it in from the environment
[ "$TRACE" = "" ] || set -xv
# Search in standard g++ prototype directory and in the current directory
# NOTE: this variable is edited by the install process
PROTODIR=/projects/gnu-cygnus/gnu-cygnus-2/mips/lib/g++-include/gen
pwd=`pwd`
case "$1" in
-catalog*|-list*)
#
# genclass -catalog [proto ...]
# genclass -list [proto ...]
#
option="$1" ;
shift ;
case $# in
0)
#
# -catalog
# -list
#
select=all ;
select_pattern=p ;
;;
*)
#
# -catalog proto ...
# -list proto ...
#
select="$@" ;
select_pattern= ;
for i in $@ ; do
select_pattern="\
$select_pattern
/.*$i\$/ p
" ;
done ;
;;
esac ;
#
# select_pattern is now a (possibly-vacuous) newline-
# separated list of patterns of the form:
#
# /.*Proto1$/ p
# /.*Proto2$/ p
# /.*Proto3$/ p
#
# or select_pattern is simply ``p'' to select everything
# Hmmm... not all systems have a fmt program; should we
# just go ahead and use ``nroff -Tcrt | cat -s'' here?
fmt='nroff -Tcrt | cat -s'
#fmt=fmt ;
case "$option" in
-catalog*)
#
# -catalog [proto ...]
#
echo "\
Catalog of ${name} class templates
directories searched:
$PROTODIR
$pwd
selecting: $select
classes available:" ;
;;
-list*)
#
# -list [proto ...]
#
# no need to do anything (the list is coming out next)
;;
esac ;
# The sed script does the following:
# - If it does not end in a .ccP or .hP then
# it's not a template and we are not intereseted.
# - Get rid of pathname components [s;.*/;;]
# - Just take the template names
# - change quoting conventions and select off what we want to see
# -if it did not pass the patterns, kill it
ls $pwd $PROTODIR | sed -e '
/\.ccP$/ !{
/\.hP$/ !{
d
}
}
s;.*/;;
s/\.ccP$//
s/\.hP$//
' -e "$select_pattern
d
" | sort -u | case "$option" in
-catalog*)
# The library catalog information preceded the list
# format the list, and tab in in a bit to make it readable.
# Re-evaluate $fmt because it might contain a shell command
eval $fmt | sed -e 's/.*/ &/' ;
;;
-list*)
# nothing special, just let the sorted list dribble out
# we must use cat to receive (and reproduce) the incoming list
cat ;
;;
esac ;
exit 0;
;;
-2)
#
# genclass -2 type1 {ref|val} type2 {ref|val} proto [out_prefix]
#
N=2 ;
case $# in
6) # genclass -2 type1 {ref|val} type2 {ref|val} proto
;;
7) # genclass -2 type1 {ref|val} type2 {ref|val} proto out_prefix
;;
*)
echo "usage: $usage" 1>&2 ;
exit 1;
esac ;
shift ;
;;
*)
#
# genclass type1 {ref|val} proto [out_prefix]
#
N=1 ;
case $# in
3) # genclass type1 {ref|val} proto
;;
4) # genclass type1 {ref|val} proto out_prefix
;;
*)
echo "usage: $usage" 1>&2 ;
exit 1;
esac ;
;;
esac
#
# Args are now (the point being the leading ``-2'' is gone)
#
# type1 {ref|val} proto [out_prefix]
# type1 {ref|val} type2 {ref|val} proto [out_prefix]
#
#
# Quote all of the $1 $2 etc references to guard against
# dynamic syntax errors due to vacuous arguments (i.e. '')
# as sometimes occurs when genclass is used from a Makefile
#
T1="$1";
T1NAME="$T1." ;
T1SEDNAME="$T1" ;
case "$2" in
ref)
T1ACC="\&" ;
;;
val)
T1ACC=" " ;
;;
*)
echo "${name}: Must specify type1 access as ref or val" 1>&2 ;
echo "usage: $usage" 1>&2 ;
exit 1;
;;
esac
# N is either 1 or 2
case $N in
1)
#
# type1 {ref|val} proto [out_prefix]
#
class="$3" ;
T2="" ;
T2ACC="" ;
;;
2)
#
# type1 {ref|val} type2 {ref|val} proto [out_prefix]
#
class="$5" ;
T2="$3";
T2NAME="$T2." ;
T2SEDNAME="$T2" ;
case "$4" in
ref)
T2ACC="\&" ;
;;
val)
T2ACC=" " ;
;;
*)
echo "${name}: Must specify type2 access: ref or val" 1>&2 ;
echo "usage: $usage" 1>&2 ;
exit 1;;
esac;
;;
esac
defaultprefix="$T1NAME$T2NAME" ;
case $# in
3) # type1 {ref|val} proto
replaceprefix="N" ;
prefix="$defaultprefix" ;
;;
5) # type1 {ref|val} type2 {ref|val} proto
replaceprefix="N" ;
prefix="$defaultprefix" ;
;;
4) # type1 {ref|val} proto out_prefix
prefix="$4" ;
replaceprefix="Y" ;
;;
6) # type1 {ref|val} type2 {ref|val} proto out_prefix
prefix="$6" ;
replaceprefix="Y" ;
;;
*)
echo "${name}: too many arguments" 1>&2 ;
echo "usage: $usage" 1>&2 ;
exit 1;
;;
esac ;
src_h=$class.hP
src_cc=$class.ccP
out_h=$prefix$class.h;
out_cc=$prefix$class.cc ;
#
# Note #1: The .h and .cc parts are done separately
# in case only a .h exists for the prototype
#
# Note #2: Bind the .h and .cc parts to the fullpath
# directories at the same time to ensure consistency.
#
if [ -f $pwd/$src_h ] ; then
fullsrc_h=$pwd/$src_h ;
fullsrc_cc=$pwd/$src_cc ;
elif [ -f $PROTODIR/$src_h ] ; then
fullsrc_h=$PROTODIR/$src_h ;
fullsrc_cc=$PROTODIR/$src_cc ;
else
echo "${name}: there is no prototype for class $class - file $src_h" 1>&2 ;
$0 -list ;
exit 1;
fi
CASES="$N$replaceprefix" ;
# CASES is one of { 2Y 2N 1Y 1N }
#
# WATCHOUT - we have no way of checking whether or not
# the proper case type is being used with the prototype.
#
# For example, we have no way of ensuring that any of
# Map variants are specified with the -2 argument set
# Further, we have no way of ensuring that -2 is not
# used with the prototypes which require only one.
#
# The second problem is not serious because it still
# results in correctly-generated C++ code; the first
# problem is serious because it results in C++ code that
# still has ``<C>'' and ``<C&>'' syntax inside it. Such
# code of course will not compile.
#
# SO THE BEST WE CAN DO - is check for the presence of
# <C> and <C&> AFTER the thing has been generated.
#
case $CASES in
2Y) # Two output substitutions, change the prefix
sed < $fullsrc_h > $out_h -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/<C>/$T2/g
s/<C&>/$T2$T2ACC/g
s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
s/$T1SEDNAME\./$prefix/g
s/$T2SEDNAME\./$prefix/g
" ;
;;
2N) # Two output substitutions, use the default prefix
sed < $fullsrc_h > $out_h -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/<C>/$T2/g
s/<C&>/$T2$T2ACC/g
" ;
;;
1Y) # One output substitution, change the prefix
sed < $fullsrc_h > $out_h -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/$T1SEDNAME\./$prefix/g
" ;
;;
1N) # One output substitution, use the default prefix
sed < $fullsrc_h > $out_h -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
" ;
;;
esac
if egrep '<C&?>' $out_h > /dev/null ; then
echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
echo "usage: $usage" 1>&2 ;
# the user does not get to see the mistakes (he might try to compile it)
rm $out_h ;
exit 1;
fi ;
if [ ! -f $fullsrc_cc ] ; then
echo "${name}: warning, class has a .h but no .cc file" 1>&2 ;
exit 0;
fi
case $CASES in
2Y) # Two output substitutions, change the prefix
sed < $fullsrc_cc > $out_cc -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/<C>/$T2/g
s/<C&>/$T2$T2ACC/g
s/$T1SEDNAME\.$T2SEDNAME\./$prefix/g
s/$T1SEDNAME\./$prefix/g
s/$T2SEDNAME\./$prefix/g
"
;;
2N) # Two output substitutions, use the default prefix
sed < $fullsrc_cc > $out_cc -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/<C>/$T2/g
s/<C&>/$T2$T2ACC/g
"
;;
1Y) # One output substitution, change the prefix
sed < $fullsrc_cc > $out_cc -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
s/$T1SEDNAME\./$prefix/g
"
;;
1N) # One output substitution, use the default prefix
sed < $fullsrc_cc > $out_cc -e "
s/<T>/$T1/g
s/<T&>/$T1$T1ACC/g
"
;;
esac
if egrep '<C&?>' $out_h $out_cc > /dev/null ; then
echo "${name}: the $class class requires the -2 syntax for the 2nd type" 1>&2 ;
echo "usage: $usage" 1>&2 ;
# the user does not get to see the mistakes (he might try to compile it)
rm $out_h $out_cc ;
exit 1;
fi ;
exit 0;

View File

@ -1,130 +0,0 @@
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988, 1992 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
converted to use iostream library by Per Bothner (bothner@cygnus.com)
This file is part of GNU CC.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY. No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing. Refer to the GNU CC General Public
License for full details.
Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License. A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice
and this notice must be preserved on all copies.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <PlotFile.h>
/*
PlotFile implementation module
*/
PlotFile& PlotFile:: cmd(char c)
{
ofstream::put(c);
return *this;
}
PlotFile& PlotFile:: operator<<(const int x)
{
#if defined(convex)
ofstream::put((char)(x>>8));
ofstream::put((char)(x&0377));
#else
ofstream::put((char)(x&0377));
ofstream::put((char)(x>>8));
#endif
return *this;
}
PlotFile& PlotFile:: operator<<(const char *s)
{
*(ofstream*)this << s;
return *this;
}
PlotFile& PlotFile:: arc(const int xi, const int yi,
const int x0, const int y0,
const int x1, const int y1)
{
return cmd('a') << xi << yi << x0 << y0 << x1 << y1;
}
PlotFile& PlotFile:: box(const int x0, const int y0,
const int x1, const int y1)
{
line(x0, y0, x0, y1);
line(x0, y1, x1, y1);
line(x1, y1, x1, y0);
return line(x1, y0, x0, y0);
}
PlotFile& PlotFile:: circle(const int x, const int y, const int r)
{
return cmd('c') << x << y << r;
}
PlotFile& PlotFile:: cont(const int xi, const int yi)
{
return cmd('n') << xi << yi;
}
PlotFile& PlotFile:: dot(const int xi, const int yi, const int dx,
int n, const int* pat)
{
cmd('d') << xi << yi << dx << n;
while (n-- > 0) *this << *pat++;
return *this;
}
PlotFile& PlotFile:: erase()
{
return cmd('e');
}
PlotFile& PlotFile:: label(const char* s)
{
return cmd('t') << s << "\n";
}
PlotFile& PlotFile:: line(const int x0, const int y0,
const int x1, const int y1)
{
return cmd('l') << x0 << y0 << x1 << y1;
}
PlotFile& PlotFile:: linemod(const char* s)
{
return cmd('f') << s << "\n";
}
PlotFile& PlotFile:: move(const int xi, const int yi)
{
return cmd('m') << xi << yi;
}
PlotFile& PlotFile:: point(const int xi, const int yi)
{
return cmd('p') << xi << yi;
}
PlotFile& PlotFile:: space(const int x0, const int y0,
const int x1, const int y1)
{
return cmd('s') << x0 << y0 << x1 << y1;
}

View File

@ -1,120 +0,0 @@
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988, 1992 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
converted to use iostream library by Per Bothner (bothner@cygnus.com)
This file is part of GNU CC.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY. No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing. Refer to the GNU CC General Public
License for full details.
Everyone is granted permission to copy, modify and redistribute
GNU CC, but only under the conditions described in the
GNU CC General Public License. A copy of this license is
supposed to have been given to you along with GNU CC so you
can know your rights and responsibilities. It should be in a
file named COPYING. Among other things, the copyright notice
and this notice must be preserved on all copies.
$Id: PlotFile.h,v 1.2 1993/08/02 17:22:28 mycroft Exp $
*/
/*
a very simple implementation of a class to output unix "plot"
format plotter files. See corresponding unix man pages for
more details.
*/
#ifndef _PlotFile_h
#ifdef __GNUG__
#pragma interface
#endif
#define _PlotFile_h
#include <fstream.h>
/*
Some plot libraries have the `box' command to draw boxes. Some don't.
`box' is included here via moves & lines to allow both possiblilties.
*/
class PlotFile : public ofstream
{
protected:
PlotFile& cmd(char c);
PlotFile& operator << (const int x);
PlotFile& operator << (const char *s);
public:
PlotFile() : ofstream() { }
PlotFile(int fd) : ofstream(fd) { }
PlotFile(const char *name, int mode=ios::out, int prot=0664)
: ofstream(name, mode, prot) { }
// PlotFile& remove() { ofstream::remove(); return *this; }
// int filedesc() { return ofstream::filedesc(); }
// const char* name() { return File::name(); }
// void setname(const char* newname) { File::setname(newname); }
// int iocount() { return File::iocount(); }
PlotFile& arc(const int xi, const int yi,
const int x0, const int y0,
const int x1, const int y1);
PlotFile& box(const int x0, const int y0,
const int x1, const int y1);
PlotFile& circle(const int x, const int y, const int r);
PlotFile& cont(const int xi, const int yi);
PlotFile& dot(const int xi, const int yi, const int dx,
int n, const int* pat);
PlotFile& erase();
PlotFile& label(const char* s);
PlotFile& line(const int x0, const int y0,
const int x1, const int y1);
PlotFile& linemod(const char* s);
PlotFile& move(const int xi, const int yi);
PlotFile& point(const int xi, const int yi);
PlotFile& space(const int x0, const int y0,
const int x1, const int y1);
};
#endif

View File

@ -1,58 +0,0 @@
/*
Copyright (C) 1988 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
This file is part of the GNU C++ Library. This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <SFile.h>
SFile::SFile(const char *filename, int size, int mode, int prot)
: fstream(filename, mode, prot)
{
sz = size;
}
SFile::SFile(int fd, int size)
: fstream(fd)
{
sz = size;
}
void SFile::open(const char *name, int size, int mode, int prot)
{
fstream::open(name, mode, prot);
sz = size;
}
SFile& SFile::get(void* x)
{
read(x, sz);
return *this;
}
SFile& SFile::put(void* x)
{
write(x, sz);
return *this;
}
SFile& SFile::operator[](long i)
{
if (rdbuf()->seekoff(i * sz, ios::beg) == EOF)
set(ios::badbit);
return *this;
}

View File

@ -1,48 +0,0 @@
// This may look like C code, but it is really -*- C++ -*-
/*
Copyright (C) 1988, 1992 Free Software Foundation
written by Doug Lea (dl@rocky.oswego.edu)
This file is part of the GNU C++ Library. This library is free
software; you can redistribute it and/or modify it under the terms of
the GNU Library General Public License as published by the Free
Software Foundation; either version 2 of the License, 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 Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$Id: SFile.h,v 1.2 1993/08/02 17:22:29 mycroft Exp $
*/
#ifndef _SFile_h
#ifdef __GNUG__
#pragma interface
#endif
#define _SFile_h 1
#include <fstream.h>
class SFile: public fstream
{
protected:
int sz; // unit size for structured binary IO
public:
SFile() : fstream() { }
SFile(int fd, int size);
SFile(const char *name, int size, int mode, int prot=0664);
void open(const char *name, int size, int mode, int prot=0664);
int size() { return sz; }
int setsize(int s) { int old = sz; sz = s; return old; }
SFile& get(void* x);
SFile& put(void* x);
SFile& operator[](long i);
};
#endif

View File

@ -1,707 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#include "ioprivate.h"
#include "editbuf.h"
#include <stddef.h>
/* NOTE: Some of the code here is taken from GNU emacs */
/* Hence this file falls under the GNU License! */
// Invariants for edit_streambuf:
// An edit_streambuf is associated with a specific edit_string,
// which again is a sub-string of a specific edit_buffer.
// An edit_streambuf is always in either get mode or put mode, never both.
// In get mode, gptr() is the current position,
// and pbase(), pptr(), and epptr() are all NULL.
// In put mode, pptr() is the current position,
// and eback(), gptr(), and egptr() are all NULL.
// Any edit_streambuf that is actively doing insertion (as opposed to
// replacing) // must have its pptr() pointing to the start of the gap.
// Only one edit_streambuf can be actively inserting into a specific
// edit_buffer; the edit_buffer's _writer field points to that edit_streambuf.
// That edit_streambuf "owns" the gap, and the actual start of the
// gap is the pptr() of the edit_streambuf; the edit_buffer::_gap_start pointer
// will only be updated on an edit_streambuf::overflow().
int edit_streambuf::truncate()
{
str->buffer->delete_range(str->buffer->tell((buf_char*)pptr()),
str->buffer->tell(str->end));
return 0;
}
#ifdef OLD_STDIO
inline void disconnect_gap_from_file(edit_buffer* buffer, FILE* fp)
{
if (buffer->gap_start_ptr != &fp->__bufp)
return;
buffer->gap_start_normal = fp->__bufp;
buffer->gap_start_ptr = &buffer->gap_start_normal;
}
#endif
void edit_streambuf::flush_to_buffer(edit_buffer* buffer)
{
if (pptr() > buffer->_gap_start && pptr() < buffer->gap_end())
buffer->_gap_start = pptr();
}
void edit_streambuf::disconnect_gap_from_file(edit_buffer* buffer)
{
if (buffer->_writer != this) return;
flush_to_buffer(buffer);
setp(pptr(),pptr());
buffer->_writer = NULL;
}
buf_index edit_buffer::tell(buf_char *ptr)
{
if (ptr <= gap_start())
return ptr - data;
else
return ptr - gap_end() + size1();
}
#if 0
buf_index buf_cookie::tell()
{
return str->buffer->tell(file->__bufp);
}
#endif
buf_index edit_buffer::tell(edit_mark*mark)
{
return tell(data + mark->index_in_buffer(this));
}
// adjust the position of the gap
void edit_buffer::move_gap(buf_offset pos)
{
if (pos < size1())
gap_left (pos);
else if (pos > size1())
gap_right (pos);
}
void edit_buffer::gap_left (int pos)
{
register buf_char *to, *from;
register int i;
int new_s1;
i = size1();
from = gap_start();
to = from + gap_size();
new_s1 = size1();
/* Now copy the characters. To move the gap down,
copy characters up. */
for (;;)
{
/* I gets number of characters left to copy. */
i = new_s1 - pos;
if (i == 0)
break;
#if 0
/* If a quit is requested, stop copying now.
Change POS to be where we have actually moved the gap to. */
if (QUITP)
{
pos = new_s1;
break;
}
#endif
/* Move at most 32000 chars before checking again for a quit. */
if (i > 32000)
i = 32000;
new_s1 -= i;
while (--i >= 0)
*--to = *--from;
}
/* Adjust markers, and buffer data structure, to put the gap at POS.
POS is where the loop above stopped, which may be what was specified
or may be where a quit was detected. */
adjust_markers (pos << 1, size1() << 1, gap_size(), data);
#ifndef OLD_STDIO
_gap_start = data + pos;
#else
if (gap_start_ptr == &gap_start_normal)
gap_start_normal = data + pos;
#endif
__gap_end_pos = to - data;
/* QUIT;*/
}
void edit_buffer::gap_right (int pos)
{
register buf_char *to, *from;
register int i;
int new_s1;
i = size1();
to = gap_start();
from = i + gap_end();
new_s1 = i;
/* Now copy the characters. To move the gap up,
copy characters down. */
while (1)
{
/* I gets number of characters left to copy. */
i = pos - new_s1;
if (i == 0)
break;
#if 0
/* If a quit is requested, stop copying now.
Change POS to be where we have actually moved the gap to. */
if (QUITP)
{
pos = new_s1;
break;
}
#endif
/* Move at most 32000 chars before checking again for a quit. */
if (i > 32000)
i = 32000;
new_s1 += i;
while (--i >= 0)
*to++ = *from++;
}
adjust_markers ((size1() + gap_size()) << 1, (pos + gap_size()) << 1,
- gap_size(), data);
#ifndef OLD_STDIO
_gap_start = data+pos;
#else
if (gap_start_ptr == &gap_start_normal)
gap_start_normal = data + pos;
#endif
__gap_end_pos = from - data;
/* QUIT;*/
}
/* make sure that the gap in the current buffer is at least k
characters wide */
void edit_buffer::make_gap(buf_offset k)
{
register buf_char *p1, *p2, *lim;
buf_char *old_data = data;
int s1 = size1();
if (gap_size() >= k)
return;
/* Get more than just enough */
if (buf_size > 1000) k += 2000;
else k += /*200;*/ 20; // for testing!
p1 = (buf_char *) realloc (data, s1 + size2() + k);
if (p1 == 0)
abort(); /*memory_full ();*/
k -= gap_size(); /* Amount of increase. */
/* Record new location of text */
data = p1;
/* Transfer the new free space from the end to the gap
by shifting the second segment upward */
p2 = data + buf_size;
p1 = p2 + k;
lim = p2 - size2();
while (lim < p2)
*--p1 = *--p2;
/* Finish updating text location data */
__gap_end_pos += k;
#ifndef OLD_STDIO
_gap_start = data + s1;
#else
if (gap_start_ptr == &gap_start_normal)
gap_start_normal = data + s1;
#endif
/* adjust markers */
adjust_markers (s1 << 1, (buf_size << 1) + 1, k, old_data);
buf_size += k;
}
/* Add `amount' to the position of every marker in the current buffer
whose current position is between `from' (exclusive) and `to' (inclusive).
Also, any markers past the outside of that interval, in the direction
of adjustment, are first moved back to the near end of the interval
and then adjusted by `amount'. */
void edit_buffer::adjust_markers(register mark_pointer low,
register mark_pointer high,
int amount, buf_char *old_data)
{
register struct edit_mark *m;
register mark_pointer mpos;
/* convert to mark_pointer */
amount <<= 1;
if (_writer)
_writer->disconnect_gap_from_file(this);
for (m = mark_list(); m != NULL; m = m->chain)
{
mpos = m->_pos;
if (amount > 0)
{
if (mpos > high && mpos < high + amount)
mpos = high + amount;
}
else
{
if (mpos > low + amount && mpos <= low)
mpos = low + amount;
}
if (mpos > low && mpos <= high)
mpos += amount;
m->_pos = mpos;
}
// Now adjust files
edit_streambuf *file;
for (file = files; file != NULL; file = file->next) {
mpos = file->current() - old_data;
if (amount > 0)
{
if (mpos > high && mpos < high + amount)
mpos = high + amount;
}
else
{
if (mpos > low + amount && mpos <= low)
mpos = low + amount;
}
if (mpos > low && mpos <= high)
mpos += amount;
char* new_pos = data + mpos;
file->set_current(new_pos, file->is_reading());
}
}
#if 0
stdio_
__off == index at start of buffer (need only be valid after seek ? )
__buf ==
if read/read_delete/overwrite mode:
__endp <= min(*gap_start_ptr, edit_string->end->ptr(buffer))
if inserting:
must have *gap_start_ptr == __bufp && *gap_start_ptr+gap == __endp
file->edit_string->end->ptr(buffer) == *gap_start_ptr+end
if write_mode:
if before gap
#endif
int edit_streambuf::underflow()
{
if (!(_mode & ios::in))
return EOF;
struct edit_buffer *buffer = str->buffer;
if (!is_reading()) { // Must switch from put to get mode.
disconnect_gap_from_file(buffer);
set_current(pptr(), 1);
}
buf_char *str_end = str->end->ptr(buffer);
retry:
if (gptr() < egptr()) {
return *gptr();
}
if ((buf_char*)gptr() == str_end)
return EOF;
if (str_end <= buffer->gap_start()) {
setg(eback(), gptr(), str_end);
goto retry;
}
if (gptr() < buffer->gap_start()) {
setg(eback(), gptr(), buffer->gap_start());
goto retry;
}
if (gptr() == buffer->gap_start()) {
disconnect_gap_from_file(buffer);
// fp->__offset += fp->__bufp - fp->__buffer;
setg(buffer->gap_end(), buffer->gap_end(), str_end);
}
else
setg(eback(), gptr(), str_end);
goto retry;
}
int edit_streambuf::overflow(int ch)
{
if (_mode == ios::in)
return EOF;
struct edit_buffer *buffer = str->buffer;
flush_to_buffer(buffer);
if (ch == EOF)
return 0;
if (is_reading()) { // Must switch from get to put mode.
set_current(gptr(), 0);
}
buf_char *str_end = str->end->ptr(buffer);
retry:
if (pptr() < epptr()) {
*pptr() = ch;
pbump(1);
return (unsigned char)ch;
}
if ((buf_char*)pptr() == str_end || inserting()) {
/* insert instead */
if (buffer->_writer)
buffer->_writer->flush_to_buffer(); // Redundant?
buffer->_writer = NULL;
if (pptr() >= buffer->gap_end())
buffer->move_gap(pptr() - buffer->gap_size());
else
buffer->move_gap(pptr());
buffer->make_gap(1);
setp(buffer->gap_start(), buffer->gap_end());
buffer->_writer = this;
*pptr() = ch;
pbump(1);
return (unsigned char)ch;
}
if (str_end <= buffer->gap_start()) {
// Entire string is left of gap.
setp(pptr(), str_end);
}
else if (pptr() < buffer->gap_start()) {
// Current pos is left of gap.
setp(pptr(), buffer->gap_start());
goto retry;
}
else if (pptr() == buffer->gap_start()) {
// Current pos is at start of gap; move to end of gap.
// disconnect_gap_from_file(buffer);
setp(buffer->gap_end(), str_end);
// __offset += __bufp - __buffer;
}
else {
// Otherwise, current pos is right of gap.
setp(pptr(), str_end);
}
goto retry;
}
void edit_streambuf::set_current(char *new_pos, int reading)
{
if (reading) {
setg(new_pos, new_pos, new_pos);
setp(NULL, NULL);
}
else {
setg(NULL, NULL, NULL);
setp(new_pos, new_pos);
}
}
// Called by fseek(fp, pos, whence) if fp is bound to a edit_buffer.
streampos edit_streambuf::seekoff(streamoff offset, _seek_dir dir,
int mode /* =ios::in|ios::out*/)
{
struct edit_buffer *buffer = str->buffer;
disconnect_gap_from_file(buffer);
buf_index cur_pos = buffer->tell((buf_char*)current());;
buf_index start_pos = buffer->tell(str->start);
buf_index end_pos = buffer->tell(str->end);
switch (dir) {
case ios::beg:
offset += start_pos;
break;
case ios::cur:
offset += cur_pos;
break;
case ios::end:
offset += end_pos;
break;
}
if (offset < start_pos || offset > end_pos)
return EOF;
buf_char *new_pos = buffer->data + offset;
buf_char* gap_start = buffer->gap_start();
if (new_pos > gap_start) {
buf_char* gap_end = buffer->gap_end();
new_pos += gap_end - gap_start;
if (new_pos >= buffer->data + buffer->buf_size) abort(); // Paranoia.
}
set_current(new_pos, is_reading());
return EOF;
}
#if 0
int buf_seek(void *arg_cookie, fpos_t * pos, int whence)
{
struct buf_cookie *cookie = arg_cookie;
FILE *file = cookie->file;
struct edit_buffer *buffer = cookie->str->buffer;
buf_char *str_start = cookie->str->start->ptr(buffer);
disconnect_gap_from_file(buffer, cookie->file);
fpos_t cur_pos, new_pos;
if (file->__bufp <= *buffer->gap_start_ptr
|| str_start >= buffer->__gap_end)
cur_pos = str_start - file->__bufp;
else
cur_pos =
(*buffer->gap_start_ptr - str_start) + (file->__bufp - __gap_end);
end_pos = ...;
switch (whence) {
case SEEK_SET:
new_pos = *pos;
break;
case SEEK_CUR:
new_pos = cur_pos + *pos;
break;
case SEEK_END:
new_pos = end_pos + *pos;
break;
}
if (new_pos > end_pos) {
seek to end_pos;
insert_nulls(new_pos - end_pos);
return;
}
if (str_start + new_pos <= *gap_start_ptr &* *gap_start_ptr < end) {
__buffer = str_start;
__off = 0;
__bufp = str_start + new_pos;
file->__get_limit =
*buffer->gap_start_ptr; /* what if gap_start_ptr == &bufp ??? */
} else if () {
}
*pos = new_pos;
}
#endif
/* Delete characters from `from' up to (but not incl) `to' */
void edit_buffer::delete_range (buf_index from, buf_index to)
{
register int numdel;
if ((numdel = to - from) <= 0)
return;
/* Make sure the gap is somewhere in or next to what we are deleting */
if (from > size1())
gap_right (from);
if (to < size1())
gap_left (to);
/* Relocate all markers pointing into the new, larger gap
to point at the end of the text before the gap. */
adjust_markers ((to + gap_size()) << 1, (to + gap_size()) << 1,
- numdel - gap_size(), data);
__gap_end_pos = to + gap_size();
_gap_start = data + from;
}
void edit_buffer::delete_range(struct edit_mark *start, struct edit_mark *end)
{
delete_range(tell(start), tell(end));
}
void buf_delete_chars(struct edit_buffer *buf, struct edit_mark *mark, size_t count)
{
abort();
}
edit_streambuf::edit_streambuf(edit_string* bstr, int mode)
{
_mode = mode;
str = bstr;
edit_buffer* buffer = bstr->buffer;
next = buffer->files;
buffer->files = this;
char* buf_ptr = bstr->start->ptr(buffer);
_inserting = 0;
// setb(buf_ptr, buf_ptr, 0);
set_current(buf_ptr, !(mode & ios::out+ios::trunc+ios::app));
if (_mode & ios::trunc)
truncate();
if (_mode & ios::ate)
seekoff(0, ios::end);
}
// Called by fclose(fp) if fp is bound to a edit_buffer.
#if 0
static int buf_close(void *arg)
{
register struct buf_cookie *cookie = arg;
struct edit_buffer *buffer = cookie->str->buffer;
struct buf_cookie **ptr;
for (ptr = &buffer->files; *ptr != cookie; ptr = &(*ptr)->next) ;
*ptr = cookie->next;
disconnect_gap_from_file(buffer, cookie->file);
free (cookie);
return 0;
}
#endif
edit_streambuf::~edit_streambuf()
{
if (_mode == ios::out)
truncate();
// Unlink this from list of files associated with bstr->buffer.
edit_streambuf **ptr = &str->buffer->files;
for (; *ptr != this; ptr = &(*ptr)->next) { }
*ptr = next;
disconnect_gap_from_file(str->buffer);
}
edit_buffer::edit_buffer()
{
buf_size = /*200;*/ 15; /* for testing! */
data = (buf_char*)malloc(buf_size);
files = NULL;
#ifndef OLD_STDIO
_gap_start = data;
_writer = NULL;
#else
gap_start_normal = data;
gap_start_ptr = &gap_start_normal;
#endif
__gap_end_pos = buf_size;
start_mark.chain = &end_mark;
start_mark._pos = 0;
end_mark.chain = NULL;
end_mark._pos = 2 * buf_size + 1;
}
// Allocate a new mark, which is adjusted by 'delta' bytes from 'this'.
// Restrict new mark to lie within 'str'.
edit_mark::edit_mark(struct edit_string *str, long delta)
{
struct edit_buffer *buf = str->buffer;
chain = buf->start_mark.chain;
buf->start_mark.chain = this;
mark_pointer size1 = buf->size1() << 1;
int gap_size = buf->gap_size() << 1;
delta <<= 1;
// check if new and old marks are opposite sides of gap
if (_pos <= size1 && _pos + delta > size1)
delta += gap_size;
else if (_pos >= size1 + gap_size && _pos + delta < size1 + gap_size)
delta -= gap_size;
_pos = _pos + delta;
if (_pos < str->start->_pos & ~1)
_pos = (str->start->_pos & ~ 1) + (_pos & 1);
else if (_pos >= str->end->_pos)
_pos = (str->end->_pos & ~ 1) + (_pos & 1);
}
// A (slow) way to find the buffer a mark belongs to.
edit_buffer * edit_mark::buffer()
{
struct edit_mark *mark;
for (mark = this; mark->chain != NULL; mark = mark->chain) ;
// Assume that the last mark on the chain is the end_mark.
return (edit_buffer *)((char*)mark - offsetof(edit_buffer, end_mark));
}
edit_mark::~edit_mark()
{
// Must unlink mark from chain of owning buffer
struct edit_buffer *buf = buffer();
if (this == &buf->start_mark || this == &buf->end_mark) abort();
edit_mark **ptr;
for (ptr = &buf->start_mark.chain; *ptr != this; ptr = &(*ptr)->chain) ;
*ptr = this->chain;
}
int edit_string::length() const
{
ptrdiff_t delta = end->ptr(buffer) - start->ptr(buffer);
if (end->ptr(buffer) <= buffer->gap_start() ||
start->ptr(buffer) >= buffer->gap_end())
return delta;
return delta - buffer->gap_size();
}
buf_char * edit_string::copy_bytes(int *lenp) const
{
char *new_str;
int len1, len2;
buf_char *start1, *start2;
start1 = start->ptr(buffer);
if (end->ptr(buffer) <= buffer->gap_start()
|| start->ptr(buffer) >= buffer->gap_end()) {
len1 = end->ptr(buffer) - start1;
len2 = 0;
start2 = NULL; // To avoid a warning from g++.
}
else {
len1 = buffer->gap_start() - start1;
start2 = buffer->gap_end();
len2 = end->ptr(buffer) - start2;
}
new_str = (char*)malloc(len1 + len2 + 1);
memcpy(new_str, start1, len1);
if (len2 > 0) memcpy(new_str + len1, start2, len2);
new_str[len1+len2] = '\0';
*lenp = len1+len2;
return new_str;
}
// Replace the buf_chars in 'this' with ones from 'src'.
// Equivalent to deleting this, then inserting src, except tries
// to leave marks in place: Marks whose offset from the start
// of 'this' is less than 'src->length()' will still have the
// same offset in 'this' when done.
void edit_string::assign(struct edit_string *src)
{
edit_streambuf dst_file(this, ios::out);
if (buffer == src->buffer /*&& ???*/) { /* overly conservative */
int src_len;
buf_char *new_str;
new_str = src->copy_bytes(&src_len);
dst_file.sputn(new_str, src_len);
free (new_str);
} else {
edit_streambuf src_file(src, ios::in);
for ( ; ; ) {
int ch = src_file.sbumpc();
if (ch == EOF) break;
dst_file.sputc(ch);
}
}
}

View File

@ -1,175 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: editbuf.h,v 1.2 1993/08/02 17:22:30 mycroft Exp $
#ifndef _EDITBUF_H
#define _EDITBUF_H
#ifdef __GNUG__
#pragma interface
#endif
#include <stdio.h>
#include <fstream.h>
typedef unsigned long mark_pointer;
// At some point, it might be nice to parameterize this code
// in terms of buf_char.
typedef /*unsigned*/ char buf_char;
// Logical pos from start of buffer (does not count gap).
typedef long buf_index;
// Pos from start of buffer, possibly including gap_size.
typedef long buf_offset;
#if 0
struct buf_cookie {
FILE *file;
struct edit_string *str;
struct buf_cookie *next;
buf_index tell();
};
#endif
struct edit_buffer;
struct edit_mark;
// A edit_string is defined as the region between the 'start' and 'end' marks.
// Normally (always?) 'start->insert_before()' should be false,
// and 'end->insert_before()' should be true.
struct edit_string {
struct edit_buffer *buffer; // buffer that 'start' and 'end' belong to
struct edit_mark *start, *end;
int length() const; // count of buf_chars currently in string
edit_string(struct edit_buffer *b,
struct edit_mark *ms, struct edit_mark *me)
{ buffer = b; start = ms; end = me; }
/* Make a fresh, contiguous copy of the data in STR.
Assign length of STR to *LENP.
(Output has extra NUL at out[*LENP].) */
buf_char *copy_bytes(int *lenp) const;
// FILE *open_file(char *mode);
void assign(struct edit_string *src); // copy bytes from src to this
};
struct edit_streambuf : public streambuf {
friend edit_buffer;
edit_string *str;
edit_streambuf* next; // Chain of edit_streambuf's for a edit_buffer.
short _mode;
edit_streambuf(edit_string* bstr, int mode);
~edit_streambuf();
virtual int underflow();
virtual int overflow(int c = EOF);
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
void flush_to_buffer();
void flush_to_buffer(edit_buffer* buffer);
int _inserting;
int inserting() { return _inserting; }
void inserting(int i) { _inserting = i; }
// int delete_chars(int count, char* cut_buf); Not implemented.
int truncate();
int is_reading() { return gptr() != NULL; }
buf_char* current() { return is_reading() ? gptr() : pptr(); }
void set_current(char *p, int is_reading);
protected:
void disconnect_gap_from_file(edit_buffer* buffer);
};
// A 'edit_mark' indicates a position in a buffer.
// It is "attached" the text (rather than the offset).
// There are two kinds of mark, which have different behavior
// when text is inserted at the mark:
// If 'insert_before()' is true the mark will be adjusted to be
// *after* the new text.
struct edit_mark {
struct edit_mark *chain;
mark_pointer _pos;
inline int insert_before() { return _pos & 1; }
inline unsigned long index_in_buffer(struct edit_buffer *buffer)
{ return _pos >> 1; }
inline buf_char *ptr(struct edit_buffer *buf);
buf_index tell();
edit_mark() { }
edit_mark(struct edit_string *str, long delta);
edit_buffer *buffer();
~edit_mark();
};
// A 'edit_buffer' consists of a sequence of buf_chars (the data),
// a list of edit_marks pointing into the data, and a list of FILEs
// also pointing into the data.
// A 'edit_buffer' coerced to a edit_string is the string of
// all the buf_chars in the buffer.
// This implementation uses a conventional buffer gap (as in Emacs).
// The gap start is defined by de-referencing a (buf_char**).
// This is because sometimes a FILE is inserting into the buffer,
// so rather than having each putc adjust the gap, we use indirection
// to have the gap be defined as the write pointer of the FILE.
// (This assumes that putc adjusts a pointer (as in GNU's libc), not an index.)
struct edit_buffer {
buf_char *data; /* == emacs buffer_text.p1+1 */
buf_char *_gap_start;
edit_streambuf* _writer; // If non-NULL, currently writing stream
inline buf_char *gap_start()
{ return _writer ? _writer->pptr() : _gap_start; }
buf_offset __gap_end_pos; // size of part 1 + size of gap
/* int gap; implicit: buf_size - size1 - size2 */
int buf_size;
struct edit_streambuf *files;
struct edit_mark start_mark;
struct edit_mark end_mark;
edit_buffer();
inline buf_offset gap_end_pos() { return __gap_end_pos; }
inline struct edit_mark *start_marker() { return &start_mark; }
inline struct edit_mark *end_marker() { return &end_mark; }
/* these should be protected, ultimately */
buf_index tell(edit_mark*);
buf_index tell(buf_char*);
inline buf_char *gap_end() { return data + gap_end_pos(); }
inline int gap_size() { return gap_end() - gap_start(); }
inline int size1() { return gap_start() - data; }
inline int size2() { return buf_size - gap_end_pos(); }
inline struct edit_mark * mark_list() { return &start_mark; }
void make_gap (buf_offset);
void move_gap (buf_offset pos);
void move_gap (buf_char *pos) { move_gap(pos - data); }
void gap_left (int pos);
void gap_right (int pos);
void adjust_markers(mark_pointer low, mark_pointer high,
int amount, buf_char *old_data);
void delete_range(buf_index from, buf_index to);
void delete_range(struct edit_mark *start, struct edit_mark *end);
};
extern buf_char * bstr_copy(struct edit_string *str, int *lenp);
// Convert a edit_mark to a (buf_char*)
inline buf_char *edit_mark::ptr(struct edit_buffer *buf)
{ return buf->data + index_in_buffer(buf); }
inline void edit_streambuf::flush_to_buffer()
{
edit_buffer* buffer = str->buffer;
if (buffer->_writer == this) flush_to_buffer(buffer);
}
#endif /* !_EDITBUF_H*/

View File

@ -1,580 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991, 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
// An fstream can be in at most one of put mode, get mode, or putback mode.
// Putback mode is a variant of get mode.
// In a filebuf, there is only one current position, instead of two
// separate get and put pointers. In get mode, the current posistion
// is that of gptr(); in put mode that of pptr().
// The position in the buffer that corresponds to the position
// in external file system is file_ptr().
// This is normally egptr(), except in putback mode, when it is _save_egptr.
// If the field _fb._offset is >= 0, it gives the offset in
// the file as a whole corresponding to eGptr(). (???)
// PUT MODE:
// If a filebuf is in put mode, pbase() is non-NULL and equal to base().
// Also, epptr() == ebuf().
// Also, eback() == gptr() && gptr() == egptr().
// The un-flushed character are those between pbase() and pptr().
// GET MODE:
// If a filebuf is in get or putback mode, eback() != egptr().
// In get mode, the unread characters are between gptr() and egptr().
// The OS file position corresponds to that of egptr().
// PUTBACK MODE:
// Putback mode is used to remember "excess" characters that have
// been sputbackc'd in a separate putback buffer.
// In putback mode, the get buffer points to the special putback buffer.
// The unread characters are the characters between gptr() and egptr()
// in the putback buffer, as well as the area between save_gptr()
// and save_egptr(), which point into the original reserve buffer.
// (The pointers save_gptr() and save_egptr() are the values
// of gptr() and egptr() at the time putback mode was entered.)
// The OS position corresponds to that of save_egptr().
//
// LINE BUFFERED OUTPUT:
// During line buffered output, pbase()==base() && epptr()==base().
// However, ptr() may be anywhere between base() and ebuf().
// This forces a call to filebuf::overflow(int C) on every put.
// If there is more space in the buffer, and C is not a '\n',
// then C is inserted, and pptr() incremented.
//
// UNBUFFERED STREAMS:
// If a filebuf is unbuffered(), the _shortbuf[1] is used as the buffer.
#define CLOSED_FILEBUF_FLAGS \
(_S_IS_FILEBUF+_S_NO_READS+_S_NO_WRITES+_S_TIED_PUT_GET)
void filebuf::init()
{
_fb._offset = 0;
_link_in();
_fb._fileno = -1;
}
filebuf::filebuf() : backupbuf(CLOSED_FILEBUF_FLAGS)
{
init();
}
filebuf::filebuf(int fd) : backupbuf(CLOSED_FILEBUF_FLAGS)
{
init();
attach(fd);
}
filebuf::filebuf(int fd, char* p, int len) : backupbuf(CLOSED_FILEBUF_FLAGS)
{
init();
attach(fd);
setbuf(p, len);
}
filebuf::~filebuf()
{
if (!(xflags() & _S_DELETE_DONT_CLOSE))
close();
_un_link();
}
filebuf* filebuf::open(const char *filename, ios::openmode mode, int prot)
{
if (is_open())
return NULL;
int posix_mode;
int read_write;
if (mode & ios::app)
mode |= ios::out;
if ((mode & (ios::in|ios::out)) == (ios::in|ios::out)) {
posix_mode = O_RDWR;
read_write = 0;
}
else if (mode & ios::out)
posix_mode = O_WRONLY, read_write = _S_NO_READS;
else if (mode & (int)ios::in)
posix_mode = O_RDONLY, read_write = _S_NO_WRITES;
else
posix_mode = 0, read_write = _S_NO_READS+_S_NO_WRITES;
if ((mode & (int)ios::trunc) || mode == (int)ios::out)
posix_mode |= O_TRUNC;
if (mode & ios::app)
posix_mode |= O_APPEND, read_write |= _S_IS_APPENDING;
if (!(mode & (int)ios::nocreate) && mode != ios::in)
posix_mode |= O_CREAT;
if (mode & (int)ios::noreplace)
posix_mode |= O_EXCL;
int fd = ::open(filename, posix_mode, prot);
if (fd < 0)
return NULL;
_fb._fileno = fd;
xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING);
if (mode & (ios::ate|ios::app)) {
if (seekoff(0, ios::end) == EOF)
return NULL;
}
_link_in();
return this;
}
filebuf* filebuf::open(const char *filename, const char *mode)
{
if (is_open())
return NULL;
int oflags = 0, omode;
int read_write;
int oprot = 0666;
switch (*mode++) {
case 'r':
omode = O_RDONLY;
read_write = _S_NO_WRITES;
break;
case 'w':
omode = O_WRONLY;
oflags = O_CREAT|O_TRUNC;
read_write = _S_NO_READS;
break;
case 'a':
omode = O_WRONLY;
oflags = O_CREAT|O_APPEND;
read_write = _S_NO_READS|_S_IS_APPENDING;
break;
default:
errno = EINVAL;
return NULL;
}
if (mode[0] == '+' || (mode[0] == 'b' && mode[1] == '+')) {
omode = O_RDWR;
read_write &= _S_IS_APPENDING;
}
int fdesc = ::open(filename, omode|oflags, oprot);
if (fdesc < 0)
return NULL;
_fb._fileno = fdesc;
xsetflags(read_write, _S_NO_READS+_S_NO_WRITES+_S_IS_APPENDING);
if (read_write & _S_IS_APPENDING)
if (seekoff(0, ios::end) == EOF)
return NULL;
_link_in();
return this;
}
filebuf* filebuf::attach(int fd)
{
if (is_open())
return NULL;
_fb._fileno = fd;
xsetflags(0, _S_NO_READS+_S_NO_WRITES);
return this;
}
streambuf* filebuf::setbuf(char* p, int len)
{
if (streambuf::setbuf(p, len) == NULL)
return NULL;
setp(_base, _base);
setg(_base, _base, _base);
return this;
}
int filebuf::overflow(int c)
{
if (xflags() & _S_NO_WRITES) // SET ERROR
return EOF;
// Allocate a buffer if needed.
if (base() == NULL) {
doallocbuf();
if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(_base, _base);
else setp(_base, _ebuf);
setg(_base, _base, _base);
_flags |= _S_CURRENTLY_PUTTING;
}
// If currently reading, switch to writing.
else if ((_flags & _S_CURRENTLY_PUTTING) == 0) {
if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(gptr(), gptr());
else setp(gptr(), ebuf());
setg(egptr(), egptr(), egptr());
_flags |= _S_CURRENTLY_PUTTING;
}
if (c == EOF)
return do_flush();
if (pptr() == ebuf() ) // Buffer is really full
if (do_flush() == EOF)
return EOF;
xput_char(c);
if (unbuffered() || (linebuffered() && c == '\n'))
if (do_flush() == EOF)
return EOF;
return (unsigned char)c;
}
int filebuf::underflow()
{
#if 0
/* SysV does not make this test; take it out for compatibility */
if (fp->_flags & __SEOF)
return (EOF);
#endif
if (xflags() & _S_NO_READS)
return EOF;
if (gptr() < egptr())
return *(unsigned char*)gptr();
allocbuf();
// FIXME This can/should be moved to __streambuf ??
if ((xflags() & _S_LINE_BUF) || unbuffered()) {
// Flush all line buffered files before reading.
streambuf::flush_all_linebuffered();
}
switch_to_get_mode();
_G_ssize_t count = sys_read(base(), ebuf() - base());
if (count <= 0) {
if (count == 0)
xsetflags(_S_EOF_SEEN);
else
xsetflags(_S_ERR_SEEN), count = 0;
}
setg(base(), base(), base() + count);
setp(base(), base());
if (count == 0)
return EOF;
if (_fb._offset >= 0)
_fb._offset += count;
return *(unsigned char*)gptr();
}
int filebuf::do_write(const char *data, int to_do)
{
if (to_do == 0)
return 0;
if (xflags() & _S_IS_APPENDING) {
// On a system without a proper O_APPEND implementation,
// you would need to sys_seek(0, ios::end) here, but is
// is not needed nor desirable for Unix- or Posix-like systems.
// Instead, just indicate that offset (before and after) is
// unpredictable.
_fb._offset = -1;
}
else if (egptr() != pbase()) {
long new_pos = sys_seek(pbase()-egptr(), ios::cur);
if (new_pos == -1)
return EOF;
_fb._offset = new_pos;
}
_G_ssize_t count = sys_write(data, to_do);
if (_cur_column)
_cur_column = __adjust_column(_cur_column - 1, data, to_do) + 1;
setg(base(), base(), base());
if (xflags() & _S_LINE_BUF+_S_UNBUFFERED) setp(base(), base());
else setp(base(), ebuf());
return count != to_do ? EOF : 0;
}
int filebuf::sync()
{
// char* ptr = cur_ptr();
if (pptr() > pbase())
if (do_flush()) return EOF;
if (gptr() != egptr()) {
streampos delta = gptr() - egptr();
if (in_backup())
delta -= eGptr() - Gbase();
_G_fpos_t new_pos = sys_seek(delta, ios::cur);
if (new_pos == EOF)
return EOF;
_fb._offset = new_pos;
setg(eback(), gptr(), gptr());
}
// FIXME: Cleanup - can this be shared?
// setg(base(), ptr, ptr);
return 0;
}
streampos filebuf::seekoff(streamoff offset, _seek_dir dir, int mode)
{
streampos result, new_offset, delta;
_G_ssize_t count;
if (mode == 0) // Don't move any pointers.
dir = ios::cur, offset = 0;
// Flush unwritten characters.
// (This may do an unneeded write if we seek within the buffer.
// But to be able to switch to reading, we would need to set
// egptr to ptr. That can't be done in the current design,
// which assumes file_ptr() is eGptr. Anyway, since we probably
// end up flushing when we close(), it doesn't make much difference.)
if (pptr() > pbase() || put_mode())
if (switch_to_get_mode()) return EOF;
if (base() == NULL) {
doallocbuf();
setp(base(), base());
setg(base(), base(), base());
}
switch (dir) {
case ios::cur:
if (_fb._offset < 0) {
_fb._offset = sys_seek(0, ios::cur);
if (_fb._offset < 0)
return EOF;
}
// Make offset absolute, assuming current pointer is file_ptr().
offset += _fb._offset;
offset -= _egptr - _gptr;
if (in_backup())
offset -= _other_egptr - _other_gbase;
dir = ios::beg;
break;
case ios::beg:
break;
case ios::end:
struct stat st;
if (sys_stat(&st) == 0 && S_ISREG(st.st_mode)) {
offset += st.st_size;
dir = ios::beg;
}
else
goto dumb;
}
// At this point, dir==ios::beg.
// If destination is within current buffer, optimize:
if (_fb._offset >= 0 && _eback != NULL) {
// Offset relative to start of main get area.
_G_fpos_t rel_offset = offset - _fb._offset
+ (eGptr()-Gbase());
if (rel_offset >= 0) {
if (in_backup())
switch_to_main_get_area();
if (rel_offset <= _egptr - _eback) {
setg(base(), base() + rel_offset, egptr());
setp(base(), base());
return offset;
}
// If we have streammarkers, seek forward by reading ahead.
if (have_markers()) {
int to_skip = rel_offset - (_gptr - _eback);
if (ignore(to_skip) != to_skip)
goto dumb;
return offset;
}
}
if (rel_offset < 0 && rel_offset >= Bbase() - Bptr()) {
if (!in_backup())
switch_to_backup_area();
gbump(_egptr + rel_offset - gptr());
return offset;
}
}
unsave_markers();
// Try to seek to a block boundary, to improve kernel page management.
new_offset = offset & ~(ebuf() - base() - 1);
delta = offset - new_offset;
if (delta > ebuf() - base()) {
new_offset = offset;
delta = 0;
}
result = sys_seek(new_offset, ios::beg);
if (result < 0)
return EOF;
if (delta == 0)
count = 0;
else {
count = sys_read(base(), ebuf()-base());
if (count < delta) {
// We weren't allowed to read, but try to seek the remainder.
offset = count == EOF ? delta : delta-count;
dir = ios::cur;
goto dumb;
}
}
setg(base(), base()+delta, base()+count);
setp(base(), base());
_fb._offset = result + count;
xflags(xflags() & ~ _S_EOF_SEEN);
return offset;
dumb:
unsave_markers();
result = sys_seek(offset, dir);
if (result != EOF) {
xflags(xflags() & ~_S_EOF_SEEN);
}
_fb._offset = result;
setg(base(), base(), base());
setp(base(), base());
return result;
}
filebuf* filebuf::close()
{
if (!is_open())
return NULL;
// This flushes as well as switching mode.
if (pptr() > pbase() || put_mode())
if (switch_to_get_mode()) return NULL;
unsave_markers();
int status = sys_close();
// Free buffer.
setb(NULL, NULL, 0);
setg(NULL, NULL, NULL);
setp(NULL, NULL);
_un_link();
_flags = _IO_MAGIC|CLOSED_FILEBUF_FLAGS;
_fb._fileno = EOF;
_fb._offset = 0;
return status < 0 ? NULL : this;
}
_G_ssize_t filebuf::sys_read(char* buf, size_t size)
{
for (;;) {
_G_ssize_t count = ::read(_fb._fileno, buf, size);
if (count != -1 || errno != EINTR)
return count;
}
}
_G_fpos_t filebuf::sys_seek(_G_fpos_t offset, _seek_dir dir)
{
return ::lseek(fd(), offset, (int)dir);
}
_G_ssize_t filebuf::sys_write(const void *buf, long n)
{
long to_do = n;
while (to_do > 0) {
_G_ssize_t count = ::write(fd(), buf, to_do);
if (count == EOF) {
if (errno == EINTR)
continue;
else {
_flags |= _S_ERR_SEEN;
break;
}
}
to_do -= count;
buf = (void*)((char*)buf + count);
}
n -= to_do;
if (_fb._offset >= 0)
_fb._offset += n;
return n;
}
int filebuf::sys_stat(void* st)
{
return ::_fstat(fd(), (struct stat*)st);
}
int filebuf::sys_close()
{
return ::close(fd());
}
int filebuf::xsputn(const char *s, int n)
{
if (n <= 0)
return 0;
// This is an optimized implementation.
// If the amount to be written straddles a block boundary
// (or the filebuf is unbuffered), use sys_write directly.
int to_do = n;
int must_flush = 0;
// First figure out how much space is available in the buffer.
int count = _epptr - _pptr; // Space available.
if (linebuffered() && (_flags & _S_CURRENTLY_PUTTING)) {
count =_ebuf - _pptr;
if (count >= n) {
for (register const char *p = s + n; p > s; ) {
if (*--p == '\n') {
count = p - s + 1;
must_flush = 1;
break;
}
}
}
}
// Then fill the buffer.
if (count > 0) {
if (count > to_do)
count = to_do;
if (count > 20) {
memcpy(pptr(), s, count);
s += count;
}
else {
register char *p = pptr();;
for (register int i = count; --i >= 0; ) *p++ = *s++;
}
pbump(count);
to_do -= count;
}
if (to_do + must_flush > 0) {
// Next flush the (full) buffer.
if (__overflow(this, EOF) == EOF)
return n - to_do;
// Try to maintain alignment: write a whole number of blocks.
// dont_write is what gets left over.
int block_size = _ebuf - _base;
int dont_write = block_size >= 128 ? to_do % block_size : 0;
_G_ssize_t count = to_do - dont_write;
if (do_write(s, count) == EOF)
return n - to_do;
to_do = dont_write;
// Now write out the remainder. Normally, this will fit in the
// buffer, but it's somewhat messier for line-buffered files,
// so we let streambuf::sputn handle the general case.
if (dont_write)
to_do -= streambuf::sputn(s+count, dont_write);
}
return n - to_do;
}
int filebuf::xsgetn(char *s, int n)
{
// FIXME: OPTIMIZE THIS (specifically, when unbuffered()).
return streambuf::xsgetn(s, n);
}
// Non-ANSI AT&T-ism: Default open protection.
const int filebuf::openprot = 0644;

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: floatio.h,v 1.2 1993/08/02 17:22:31 mycroft Exp $
*/
/*
* Floating point scanf/printf (input/output) definitions.
*/
/* 11-bit exponent (VAX G floating point) is 308 decimal digits */
#define MAXEXP 308
/* 128 bit fraction takes up 39 decimal digits; max reasonable precision */
#define MAXFRACT 39

View File

@ -1,65 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#define _STREAM_COMPAT
#include "ioprivate.h"
#include <fstream.h>
fstreambase::fstreambase()
{
init(new filebuf());
}
fstreambase::fstreambase(int fd)
{
init(new filebuf(fd));
}
fstreambase::fstreambase(const char *name, int mode, int prot)
{
init(new filebuf());
if (!rdbuf()->open(name, mode, prot))
set(ios::badbit);
}
void fstreambase::open(const char *name, int mode, int prot)
{
clear();
if (!rdbuf()->open(name, mode, prot))
set(ios::badbit);
}
void fstreambase::close()
{
if (!rdbuf()->close())
set(ios::failbit);
}
#if 0
static int mode_to_sys(enum open_mode mode)
{
return O_WRONLY;
}
static char* fopen_cmd_arg(io_mode i)
{
return "w";
}
#endif

View File

@ -1,72 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: fstream.h,v 1.2 1993/08/02 17:22:32 mycroft Exp $
#ifndef _FSTREAM_H
#define _FSTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#include <iostream.h>
class fstreambase : virtual public ios {
public:
fstreambase();
fstreambase(int fd);
fstreambase(const char *name, int mode, int prot=0664);
void close();
filebuf* rdbuf() const { return (filebuf*)_strbuf; }
void open(const char *name, int mode, int prot=0664);
int is_open() const { return rdbuf()->is_open(); }
void setbuf(char *ptr, int len) { rdbuf()->setbuf(ptr, len); }
#ifdef _STREAM_COMPAT
int filedesc() { return rdbuf()->fd(); }
fstreambase& raw() { rdbuf()->setbuf(NULL, 0); return *this; }
#endif
};
class ifstream : public fstreambase, public istream {
public:
ifstream() : fstreambase() { }
ifstream(int fd) : fstreambase(fd) { }
ifstream(const char *name, int mode=ios::in, int prot=0664)
: fstreambase(name, mode, prot) { }
void open(const char *name, int mode=ios::in, int prot=0664)
{ fstreambase::open(name, mode, prot); }
};
class ofstream : public fstreambase, public ostream {
public:
ofstream() : fstreambase() { }
ofstream(int fd) : fstreambase(fd) { }
ofstream(const char *name, int mode=ios::out, int prot=0664)
: fstreambase(name, mode, prot) { }
void open(const char *name, int mode=ios::out, int prot=0664)
{ fstreambase::open(name, mode, prot); }
};
class fstream : public fstreambase, public iostream {
public:
fstream() : fstreambase() { }
fstream(int fd) : fstreambase(fd) { }
fstream(const char *name, int mode, int prot=0664)
: fstreambase(name, mode, prot) { }
void open(const char *name, int mode, int prot=0664)
{ fstreambase::open(name, mode, prot); }
};
#endif /*!_FSTREAM_H*/

View File

@ -1,135 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "iostream.h"
#include <string.h>
istream& istream::getline(char* buf, int len, char delim)
{
_gcount = 0;
if (ipfx1()) {
streambuf *sb = rdbuf();
long count = sb->sgetline(buf, len, delim, -1);
if (count == len-1)
set(ios::failbit);
else {
int ch = sb->sbumpc();
if (ch == EOF)
set(ios::failbit|ios::eofbit);
else if (ch == (unsigned char)delim)
count++;
else
sb->sungetc(); // Leave delimiter unread.
}
_gcount = count;
}
return *this;
}
istream& istream::get(char* buf, int len, char delim)
{
_gcount = 0;
if (ipfx1()) {
streambuf *sbuf = rdbuf();
long count = sbuf->sgetline(buf, len, delim, -1);
if (count < 0 || (count == 0 && sbuf->sgetc() == EOF))
set(ios::failbit|ios::eofbit);
else
_gcount = count;
}
return *this;
}
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Free Software Foundation.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// from Doug Schmidt
#define CHUNK_SIZE 512
/* Reads an arbitrarily long input line terminated by a user-specified
TERMINATOR. Super-nifty trick using recursion avoids unnecessary calls
to NEW! */
char *_sb_readline (streambuf *sb, long& total, char terminator)
{
char buf[CHUNK_SIZE+1];
char *ptr;
int ch;
long count = sb->sgetline(buf, CHUNK_SIZE+1, terminator, -1);
if (count == EOF)
return NULL;
ch = sb->sbumpc();
long old_total = total;
total += count;
if (ch != EOF && ch != terminator) {
total++; // Include ch in total.
ptr = _sb_readline(sb, total, terminator);
if (ptr) {
memcpy(ptr + old_total, buf, count);
ptr[old_total+count] = ch;
}
return ptr;
}
if (ptr = new char[total+1]) {
ptr[total] = '\0';
memcpy(ptr + total - count, buf, count);
return ptr;
}
else
return NULL;
}
/* Reads an arbitrarily long input line terminated by TERMINATOR.
This routine allocates its own memory, so the user should
only supply the address of a (char *). */
istream& istream::gets(char **s, char delim /* = '\n' */)
{
if (ipfx1()) {
long size = 0;
streambuf *sb = rdbuf();
*s = _sb_readline (sb, size, delim);
_gcount = *s ? size : 0;
if (sb->_flags & _S_EOF_SEEN) {
set(ios::eofbit);
if (_gcount == 0)
set(ios::failbit);
}
}
else {
_gcount = 0;
*s = NULL;
}
return *this;
}

View File

@ -1,48 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.h"
#include "iostream.h"
istream& istream::get(streambuf& sb, char delim /* = '\n' */)
{
_gcount = 0;
if (ipfx1()) {
register streambuf* isb = rdbuf();
for (;;) {
int len = isb->egptr() - isb->gptr();
if (len <= 0)
if (isb->underflow() == EOF)
break;
else
len = isb->egptr() - isb->gptr();
char *delimp = (char*)memchr((void*)isb->gptr(), delim, len);
if (delimp != NULL)
len = delimp - isb->gptr();
int written = sb.sputn(isb->gptr(), len);
isb->gbump(written);
_gcount += written;
if (written != len) {
set(ios::failbit);
break;
}
if (delimp != NULL)
break;
}
}
return *this;
}

View File

@ -1,108 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#include <indstream.h>
indirectbuf::indirectbuf(streambuf *get, streambuf *put, int delete_mode)
: streambuf()
{
_get_stream = get;
_put_stream = put == NULL ? get : put;
_delete_flags = delete_mode;
}
indirectbuf::~indirectbuf()
{
if (_delete_flags & ios::in) delete get_stream();
if (_delete_flags & ios::out) delete put_stream();
}
int indirectbuf::xsputn(const char* s, int n)
{
return put_stream()->sputn(s, n);
}
int indirectbuf::xsgetn(char* s, int n)
{
return get_stream()->sgetn(s, n);
}
int indirectbuf::overflow(int c /* = EOF */)
{
if (c == EOF)
return put_stream()->overflow(c);
else
return put_stream()->sputc(c);
}
int indirectbuf::underflow()
{
return get_stream()->sbumpc();
}
streampos indirectbuf::seekoff(streamoff off, _seek_dir dir, int mode)
{
int ret_val = 0;
int select = mode == 0 ? (ios::in|ios::out) : mode;
streambuf *gbuf = (select & ios::in) ? get_stream() : 0;
streambuf *pbuf = (select & ios::out) ? put_stream() : 0;
if (gbuf == pbuf)
ret_val = gbuf->seekoff(off, dir, mode);
else {
if (gbuf)
ret_val = gbuf->seekoff(off, dir, ios::in);
if (pbuf && ret_val != EOF)
ret_val = pbuf->seekoff(off, dir, ios::out);
}
return ret_val;
}
streampos indirectbuf::seekpos(streampos pos, int mode)
{
int ret_val = EOF;
int select = mode == 0 ? (ios::in|ios::out) : mode;
streambuf *gbuf = (select & ios::in) ? get_stream() : 0;
streambuf *pbuf = (select & ios::out) ? put_stream() : 0;
if (gbuf == pbuf)
ret_val = gbuf->seekpos(pos, mode);
else {
if (gbuf)
ret_val = gbuf->seekpos(pos, ios::in);
if (pbuf && ret_val != EOF)
ret_val = pbuf->seekpos(pos, ios::out);
}
return ret_val;
}
int indirectbuf::sync()
{
streambuf *gbuf = get_stream();
int ret_val = gbuf->sync();
if (ret_val == EOF) return ret_val;
streambuf *pbuf = put_stream();
if (pbuf != gbuf) return pbuf->sync();
else return ret_val;
}
int indirectbuf::pbackfail(int c)
{
return get_stream()->sputbackc(c);
}

View File

@ -1,67 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: indstream.h,v 1.2 1993/08/02 17:22:33 mycroft Exp $
#ifndef _INDSTREAM_H
#define _INDSTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#include <iostream.h>
// An indirectbuf is one that forwards all of its I/O requests
// to another streambuf.
// All get-related requests are sent to get_stream().
// All put-related requests are sent to put_stream().
// An indirectbuf can be used to implement Common Lisp
// synonym-streams and two-way-streams.
//
// class synonymbuf : public indirectbuf {
// Symbol *sym;
// synonymbuf(Symbol *s) { sym = s; }
// virtual streambuf *lookup_stream(int mode) {
// return coerce_to_streambuf(lookup_value(sym)); }
// };
class indirectbuf : public streambuf {
protected:
streambuf *_get_stream; // Optional cache for get_stream().
streambuf *_put_stream; // Optional cache for put_stream().
int _delete_flags;
public:
streambuf *get_stream()
{ return _get_stream ? _get_stream : lookup_stream(ios::in); }
streambuf *put_stream()
{ return _put_stream ? _put_stream : lookup_stream(ios::out); }
virtual streambuf *lookup_stream(int/*mode*/) { return NULL; } // ERROR!
indirectbuf(streambuf *get=NULL, streambuf *put=NULL, int delete_mode=0);
virtual ~indirectbuf();
virtual int xsputn(const char* s, int n);
virtual int xsgetn(char* s, int n);
virtual int underflow();
virtual int overflow(int c = EOF);
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
virtual int sync();
virtual int pbackfail(int c);
};
#endif /* !_INDSTREAM_H */

View File

@ -1,77 +0,0 @@
// -*- C++ -*-
// This is part of the iostream library, providing parametrized manipulators
// Written by Heinz G. Seidl, Copyright (C) 1992 Cygnus Support
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
//#pragma implementation
#endif
#include "iomanip.h"
// Those functions are called through a pointer,
// thus it does not make sense, to inline them.
ios & __iomanip_setbase (ios& i, int n)
{
ios::fmtflags b;
switch (n)
{
case 8:
b = ios::oct; break;
case 10:
b = ios::dec; break;
case 16:
b = ios::hex; break;
default:
b = 0;
}
i.setf(b, ios::basefield);
return i;
}
ios & __iomanip_setfill (ios& i, int n)
{
//FIXME if ( i.flags() & ios::widechar )
i.fill( (char) n);
//FIXME else
//FIXME i.fill( (wchar) n);
return i;
}
ios & __iomanip_setprecision (ios& i, int n)
{
i.precision(n);
return i;
}
ios & __iomanip_setw (ios& i, int n)
{
i.width(n);
return i;
}
ios & __iomanip_setiosflags (ios& i, ios::fmtflags n)
{
i.setf(n,n);
return i;
}
ios & __iomanip_resetiosflags (ios& i, ios::fmtflags n)
{
i.setf(0,n);
return i;
}

View File

@ -1,152 +0,0 @@
// -*- C++ -*-
// This is part of the iostream library, providing parametrized manipulators
// Written by Heinz G. Seidl, Copyright (C) 1992 Cygnus Support
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: iomanip.h,v 1.2 1993/08/02 17:22:34 mycroft Exp $
#ifndef _IOMANIP_H
//
// Not specifying `pragma interface' causes the compiler to emit the
// template definitions in the files, where they are used.
//
//#ifdef __GNUG__
//#pragma interface
//#endif
#define _IOMANIP_H
#include <_G_config.h>
#ifndef _G_NO_TEMPLATES
#include <iostream.h>
//-----------------------------------------------------------------------------
// Parametrized Manipulators as specified by ANSI draft
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Stream Manipulators
//-----------------------------------------------------------------------------
//
template<class TP> class smanip; // TP = Type Param
template<class TP> class sapp {
ios& (*_f)(ios&, TP);
public:
sapp(ios& (*f)(ios&, TP)) : _f(f) {}
//
smanip<TP> operator()(TP a)
{ return smanip<TP>(_f, a); }
};
template <class TP> class smanip {
ios& (*_f)(ios&, TP);
TP _a;
public:
smanip(ios& (*f)(ios&, TP), TP a) : _f(f), _a(a) {}
//
friend
istream& operator>>(istream& i, const smanip<TP>& m);
friend
ostream& operator<<(ostream& o, const smanip<TP>& m);
};
template<class TP>
inline istream& operator>>(istream& i, const smanip<TP>& m)
{ (*m._f)(i, m._a); return i; }
template<class TP>
inline ostream& operator<<(ostream& o, const smanip<TP>& m)
{ (*m._f)(o, m._a); return o;}
//-----------------------------------------------------------------------------
// Input-Stream Manipulators
//-----------------------------------------------------------------------------
//
template<class TP> class imanip;
template<class TP> class iapp {
istream& (*_f)(istream&, TP);
public:
iapp(ostream& (*f)(istream&,TP)) : _f(f) {}
//
imanip<TP> operator()(TP a)
{ return imanip<TP>(_f, a); }
};
template <class TP> class imanip {
istream& (*_f)(istream&, TP);
TP _a;
public:
imanip(istream& (*f)(istream&, TP), TP a) : _f(f), _a(a) {}
//
friend
istream& operator>>(istream& i, const imanip<TP>& m)
{ return (*m._f)( i, m._a); }
};
//-----------------------------------------------------------------------------
// Output-Stream Manipulators
//-----------------------------------------------------------------------------
//
template<class TP> class omanip;
template<class TP> class oapp {
ostream& (*_f)(ostream&, TP);
public:
oapp(ostream& (*f)(ostream&,TP)) : _f(f) {}
//
omanip<TP> operator()(TP a)
{ return omanip<TP>(_f, a); }
};
template <class TP> class omanip {
ostream& (*_f)(ostream&, TP);
TP _a;
public:
omanip(ostream& (*f)(ostream&, TP), TP a) : _f(f), _a(a) {}
//
friend
ostream& operator<<(ostream& o, omanip<TP>& m)
{ return (*m._f)(o, m._a); }
};
//-----------------------------------------------------------------------------
// Available Manipulators
//-----------------------------------------------------------------------------
//
// Macro to define an iomanip function, with one argument
// The underlying function is `__iomanip_<name>'
//
#define __DEFINE_IOMANIP_FN1(type,param,function) \
extern ios& __iomanip_##function (ios&, param); \
inline type<param> function (param n) \
{ return type<param> (__iomanip_##function, n); }
__DEFINE_IOMANIP_FN1( smanip, int, setbase)
__DEFINE_IOMANIP_FN1( smanip, int, setfill)
__DEFINE_IOMANIP_FN1( smanip, int, setprecision)
__DEFINE_IOMANIP_FN1( smanip, int, setw)
__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, resetiosflags)
__DEFINE_IOMANIP_FN1( smanip, ios::fmtflags, setiosflags)
#endif /*!_G_NO_TEMPLATES*/
#endif /*!_IOMANIP_H*/

View File

@ -1,66 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: ioprivate.h,v 1.2 1993/08/02 17:22:35 mycroft Exp $
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "streambuf.h"
#include <stdarg.h>
#include <stddef.h>
#define _fstat(x, y) fstat(x,y)
#define _isatty(fd) isatty(fd)
extern int __cvt_double(double number, register int prec, int flags,
int *signp, int fmtch, char *startp, char *endp);
/*#define USE_MALLOC_BUF*/
#ifndef USE_MALLOC_BUF
#define ALLOC_BUF(size) new char[size]
#define FREE_BUF(ptr) delete [] (ptr)
#else
#define ALLOC_BUF(size) (char*)malloc(size)
#define FREE_BUF(ptr) free(ptr)
#endif
#define USE_DTOA
// Advantages:
// - Input gets closest value
// - Output emits string that when read yields identical value.
// - Handles Infinity and NaNs (but not re-readable).
// Disadvantages of dtoa:
// - May not work for all double formats.
// - Big chunck of code.
// - Not reentrant - uses atatic variables freelist,
// result, result_k in dtoa
// (plus initializes p5s, HOWORD, and LOWORD).
#ifdef USE_DTOA
extern "C" double _Xstrtod(const char *s00, char **se);
#define strtod(s, e) _Xstrtod(s, e)
extern "C" char *dtoa(double d, int mode, int ndigits,
int *decpt, int *sign, char **rve);
extern int __outfloat(double value, streambuf *sb, char mode,
int width, int precision, __fmtflags flags,
char sign_mode, char fill);
#endif

View File

@ -1,783 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991, 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#define _STREAM_COMPAT
#include "ioprivate.h"
#include <iostream.h>
#include <stdio.h> /* Needed for sprintf */
#include <ctype.h>
#include <limits.h>
#include "floatio.h"
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
//#define isspace(ch) ((ch)==' ' || (ch)=='\t' || (ch)=='\n')
istream::istream(streambuf *sb, ostream* tied) : ios(sb, tied)
{
_flags |= ios::dont_close;
_gcount = 0;
}
int skip_ws(streambuf* sb)
{
int ch;
for (;;) {
ch = sb->sbumpc();
if (ch == EOF || !isspace(ch))
return ch;
}
}
istream& istream::get(char& c)
{
if (ipfx1()) {
int ch = _strbuf->sbumpc();
if (ch == EOF) {
set(ios::eofbit|ios::failbit);
_gcount = 0;
}
else {
c = (char)ch;
_gcount = 1;
}
}
return *this;
}
int istream::peek()
{
if (!good())
return EOF;
if (_tie && rdbuf()->in_avail() == 0)
_tie->flush();
int ch = _strbuf->sgetc();
if (ch == EOF)
set(ios::eofbit);
return ch;
}
istream& istream::ignore(int n /* = 1 */, int delim /* = EOF */)
{
if (ipfx1()) {
register streambuf* sb = _strbuf;
if (delim == EOF) {
_gcount = sb->ignore(n);
return *this;
}
_gcount = 0;
for (;;) {
#if 0
if (n != MAXINT) // FIXME
#endif
if (--n < 0)
break;
int ch = sb->sbumpc();
if (ch == EOF) {
set(ios::eofbit|ios::failbit);
break;
}
_gcount++;
if (ch == delim)
break;
}
}
return *this;
}
istream& istream::read(char *s, int n)
{
if (ipfx1()) {
_gcount = _strbuf->sgetn(s, n);
if (_gcount != n)
set(ios::failbit);
}
return *this;
}
istream& istream::seekg(streampos pos)
{
pos = _strbuf->seekpos(pos, ios::in);
if (pos == streampos(EOF))
set(ios::badbit);
return *this;
}
istream& istream::seekg(streamoff off, _seek_dir dir)
{
streampos pos = _strbuf->seekoff(off, dir, ios::in);
if (pos == streampos(EOF))
set(ios::badbit);
return *this;
}
streampos istream::tellg()
{
streampos pos = _strbuf->seekoff(0, ios::cur, ios::in);
if (pos == streampos(EOF))
set(ios::badbit);
return pos;
}
istream& istream::scan(const char *format ...)
{
if (ipfx0()) {
va_list ap;
va_start(ap, format);
_strbuf->vscan(format, ap, this);
va_end(ap);
}
return *this;
}
istream& istream::vscan(const char *format, _G_va_list args)
{
if (ipfx0())
_strbuf->vscan(format, args, this);
return *this;
}
istream& istream::operator>>(char& c)
{
if (ipfx0()) {
int ch = _strbuf->sbumpc();
if (ch == EOF)
set(ios::eofbit|ios::failbit);
else
c = (char)ch;
}
return *this;
}
istream& istream::operator>>(char* ptr)
{
register char *p = ptr;
int w = width(0);
if (ipfx0()) {
register streambuf* sb = _strbuf;
for (;;)
{
int ch = sb->sbumpc();
if (ch == EOF)
{
set(p == ptr ? (ios::eofbit|ios::failbit) : (ios::eofbit));
break;
}
else if (isspace(ch))
{
sb->sputbackc(ch);
break;
}
else if (w == 1)
{
set(ios::failbit);
sb->sputbackc(ch);
break;
}
else *p++ = ch;
w--;
}
}
*p = '\0';
return *this;
}
#ifdef __GNUC__
#define LONGEST long long
#else
#define LONGEST long
#endif
static int read_int(istream& stream, unsigned LONGEST& val, int& neg)
{
if (!stream.ipfx0())
return 0;
register streambuf* sb = stream.rdbuf();
int base = 10;
int ndigits = 0;
register int ch = skip_ws(sb);
if (ch == EOF)
goto eof_fail;
neg = 0;
if (ch == '+') {
ch = skip_ws(sb);
}
else if (ch == '-') {
neg = 1;
ch = skip_ws(sb);
}
if (ch == EOF) goto eof_fail;
if (!(stream.flags() & ios::basefield)) {
if (ch == '0') {
ch = sb->sbumpc();
if (ch == EOF) {
val = 0;
return 1;
}
if (ch == 'x' || ch == 'X') {
base = 16;
ch = sb->sbumpc();
if (ch == EOF) goto eof_fail;
}
else {
sb->sputbackc(ch);
base = 8;
ch = '0';
}
}
}
else if ((stream.flags() & ios::basefield) == ios::hex)
base = 16;
else if ((stream.flags() & ios::basefield) == ios::oct)
base = 8;
val = 0;
for (;;) {
if (ch == EOF)
break;
int digit;
if (ch >= '0' && ch <= '9')
digit = ch - '0';
else if (ch >= 'A' && ch <= 'F')
digit = ch - 'A' + 10;
else if (ch >= 'a' && ch <= 'f')
digit = ch - 'a' + 10;
else
digit = 999;
if (digit >= base) {
sb->sputbackc(ch);
if (ndigits == 0)
goto fail;
else
return 1;
}
ndigits++;
val = base * val + digit;
ch = sb->sbumpc();
}
return 1;
fail:
stream.set(ios::failbit);
return 0;
eof_fail:
stream.set(ios::failbit|ios::eofbit);
return 0;
}
#define READ_INT(TYPE) \
istream& istream::operator>>(TYPE& i)\
{\
unsigned LONGEST val; int neg;\
if (read_int(*this, val, neg)) {\
if (neg) val = -val;\
i = (TYPE)val;\
}\
return *this;\
}
READ_INT(short)
READ_INT(unsigned short)
READ_INT(int)
READ_INT(unsigned int)
READ_INT(long)
READ_INT(unsigned long)
#ifdef __GNUG__
READ_INT(long long)
READ_INT(unsigned long long)
#endif
istream& istream::operator>>(double& x)
{
if (ipfx0())
scan("%lg", &x);
return *this;
}
istream& istream::operator>>(float& x)
{
if (ipfx0())
scan("%g", &x);
return *this;
}
istream& istream::operator>>(register streambuf* sbuf)
{
if (ipfx0()) {
register streambuf* inbuf = rdbuf();
// FIXME: Should optimize!
for (;;) {
register int ch = inbuf->sbumpc();
if (ch == EOF) {
set(ios::eofbit);
break;
}
if (sbuf->sputc(ch) == EOF) {
set(ios::failbit);
break;
}
}
}
return *this;
}
ostream& ostream::operator<<(char c)
{
if (opfx()) {
#if 1
// This is what the cfront implementation does.
_strbuf->sputc(c);
#else
// This is what cfront documentation and current ANSI drafts say.
int w = width(0);
char fill_char = fill();
register int padding = w > 0 ? w - 1 : 0;
register streambuf *sb = _strbuf;
if (!(flags() & ios::left)) // Default adjustment.
while (--padding >= 0) sb->sputc(fill_char);
sb->sputc(c);
if (flags() & ios::left) // Left adjustment.
while (--padding >= 0) sb->sputc(fill_char);
#endif
osfx();
}
return *this;
}
/* Write VAL on STREAM.
If SIGN<0, val is the absolute value of a negative number.
If SIGN>0, val is a signed non-negative number.
If SIGN==0, val is unsigned. */
static void write_int(ostream& stream, unsigned LONGEST val, int sign)
{
#define WRITE_BUF_SIZE (10 + sizeof(unsigned LONGEST) * 3)
char buf[WRITE_BUF_SIZE];
register char *buf_ptr = buf+WRITE_BUF_SIZE; // End of buf.
char *show_base = "";
int show_base_len = 0;
int show_pos = 0; // If 1, print a '+'.
// Now do the actual conversion, placing the result at the *end* of buf.
// Note that we use separate code for decimal, octal, and hex,
// so we can divide by optimizable constants.
if ((stream.flags() & ios::basefield) == ios::oct) { // Octal
do {
*--buf_ptr = (val & 7) + '0';
val = val >> 3;
} while (val != 0);
if ((stream.flags() & ios::showbase) && (val != 0))
*--buf_ptr = '0';
}
else if ((stream.flags() & ios::basefield) == ios::hex) { // Hex
char *xdigs = (stream.flags() & ios::uppercase) ? "0123456789ABCDEF0X"
: "0123456789abcdef0x";
do {
*--buf_ptr = xdigs[val & 15];
val = val >> 4;
} while (val != 0);
if ((stream.flags() & ios::showbase) && (val != 0)) {
show_base = xdigs + 16; // Either "0X" or "0x".
show_base_len = 2;
}
}
else { // Decimal
#ifdef __GNUC__
// Optimization: Only use long long when we need to.
while (val > UINT_MAX) {
*--buf_ptr = (val % 10) + '0';
val /= 10;
}
// Use more efficient (int) arithmetic for the rest.
register unsigned int ival = (unsigned int)val;
#else
register unsigned LONGEST ival = val;
#endif
do {
*--buf_ptr = (ival % 10) + '0';
ival /= 10;
} while (ival != 0);
if (sign > 0 && (stream.flags() & ios::showpos))
show_pos=1;
}
int buf_len = buf+WRITE_BUF_SIZE - buf_ptr;
int w = stream.width(0);
// Calculate padding.
int len = buf_len+show_pos;
if (sign < 0) len++;
len += show_base_len;
int padding = len > w ? 0 : w - len;
// Do actual output.
register streambuf* sbuf = stream.rdbuf();
ios::fmtflags pad_kind =
stream.flags() & (ios::left|ios::right|ios::internal);
char fill_char = stream.fill();
if (padding > 0
&& pad_kind != (ios::fmtflags)ios::left
&& pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
sbuf->padn(fill_char, padding);
if (sign < 0) sbuf->sputc('-');
else if (show_pos) sbuf->sputc('+');
if (show_base_len)
sbuf->sputn(show_base, show_base_len);
if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
sbuf->padn(fill_char, padding);
sbuf->sputn(buf_ptr, buf_len);
if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
sbuf->padn(fill_char, padding);
stream.osfx();
}
ostream& ostream::operator<<(int n)
{
if (opfx()) {
int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
n = -n, sign = -1;
write_int(*this, n, sign);
}
return *this;
}
ostream& ostream::operator<<(unsigned int n)
{
if (opfx())
write_int(*this, n, 0);
return *this;
}
ostream& ostream::operator<<(long n)
{
if (opfx()) {
int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
n = -n, sign = -1;
write_int(*this, n, sign);
}
return *this;
}
ostream& ostream::operator<<(unsigned long n)
{
if (opfx())
write_int(*this, n, 0);
return *this;
}
#ifdef __GNUG__
ostream& ostream::operator<<(long long n)
{
if (opfx()) {
int sign = 1;
if (n < 0 && (flags() & (ios::oct|ios::hex)) == 0)
n = -n, sign = -1;
write_int(*this, n, sign);
}
return *this;
}
ostream& ostream::operator<<(unsigned long long n)
{
if (opfx())
write_int(*this, n, 0);
return *this;
}
#endif /*__GNUG__*/
ostream& ostream::operator<<(double n)
{
if (opfx()) {
// Uses __cvt_double (renamed from static cvt), in Chris Torek's
// stdio implementation. The setup code uses the same logic
// as in __vsbprintf.C (also based on Torek's code).
int format_char;
#if 0
if (flags() ios::showpos) sign = '+';
#endif
if ((flags() & ios::floatfield) == ios::fixed)
format_char = 'f';
else if ((flags() & ios::floatfield) == ios::scientific)
format_char = flags() & ios::uppercase ? 'E' : 'e';
else
format_char = flags() & ios::uppercase ? 'G' : 'g';
int fpprec = 0; // 'Extra' (suppressed) floating precision.
int prec = precision();
if (prec > MAXFRACT) {
if (flags() & (ios::fixed|ios::scientific) & ios::showpos)
fpprec = prec - MAXFRACT;
prec = MAXFRACT;
}
else if (prec <= 0 && !(flags() & ios::fixed))
prec = 6; /* default */
// Do actual conversion.
#ifdef USE_DTOA
if (__outfloat(n, rdbuf(), format_char, width(0),
prec, flags(), 0, fill()) < 0)
set(ios::badbit|ios::failbit); // ??
#else
int negative;
char buf[BUF];
int sign = '\0';
char *cp = buf;
*cp = 0;
int size = __cvt_double(n, prec,
flags() & ios::showpoint ? 0x80 : 0,
&negative,
format_char, cp, buf + sizeof(buf));
if (negative) sign = '-';
if (*cp == 0)
cp++;
// Calculate padding.
int fieldsize = size + fpprec;
if (sign) fieldsize++;
int padding = 0;
int w = width(0);
if (fieldsize < w)
padding = w - fieldsize;
// Do actual output.
register streambuf* sbuf = rdbuf();
register i;
char fill_char = fill();
ios::fmtflags pad_kind =
flags() & (ios::left|ios::right|ios::internal);
if (pad_kind != (ios::fmtflags)ios::left // Default (right) adjust.
&& pad_kind != (ios::fmtflags)ios::internal)
for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
if (sign)
sbuf->sputc(sign);
if (pad_kind == (ios::fmtflags)ios::internal)
for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
// Emit the actual concented field, followed by extra zeros.
sbuf->sputn(cp, size);
for (i = fpprec; --i >= 0; ) sbuf->sputc('0');
if (pad_kind == (ios::fmtflags)ios::left) // Left adjustment
for (i = padding; --i >= 0; ) sbuf->sputc(fill_char);
#endif
osfx();
}
return *this;
}
ostream& ostream::operator<<(const char *s)
{
if (opfx()) {
if (s == NULL)
s = "(null)";
int len = strlen(s);
int w = width(0);
char fill_char = fill();
register streambuf *sbuf = rdbuf();
register int padding = w > len ? w - len : 0;
if (!(flags() & ios::left)) // Default adjustment.
while (--padding >= 0) sbuf->sputc(fill_char);
sbuf->sputn(s, len);
if (flags() & ios::left) // Left adjustment.
while (--padding >= 0) sbuf->sputc(fill_char);
osfx();
}
return *this;
}
ostream& ostream::operator<<(const void *p)
{
if (opfx()) {
form("%p", p);
osfx();
}
return *this;
}
ostream& ostream::operator<<(register streambuf* sbuf)
{
if (opfx()) {
register streambuf* outbuf = rdbuf();
// FIXME: Should optimize!
for (;;) {
register int ch = sbuf->sbumpc();
if (ch == EOF) break;
if (outbuf->sputc(ch) == EOF) {
set(ios::badbit);
break;
}
}
osfx();
}
return *this;
}
ostream::ostream(streambuf* sb, ostream* tied) : ios(sb, tied)
{
_flags |= ios::dont_close;
}
ostream& ostream::seekp(streampos pos)
{
pos = _strbuf->seekpos(pos, ios::out);
if (pos == streampos(EOF))
set(ios::badbit);
return *this;
}
ostream& ostream::seekp(streamoff off, _seek_dir dir)
{
streampos pos = _strbuf->seekoff(off, dir, ios::out);
if (pos == streampos(EOF))
set(ios::badbit);
return *this;
}
streampos ostream::tellp()
{
streampos pos = _strbuf->seekoff(0, ios::cur, ios::out);
if (pos == streampos(EOF))
set(ios::badbit);
return pos;
}
ostream& ostream::form(const char *format ...)
{
if (opfx()) {
va_list ap;
va_start(ap, format);
_strbuf->vform(format, ap);
va_end(ap);
}
return *this;
}
ostream& ostream::vform(const char *format, _G_va_list args)
{
if (opfx())
_strbuf->vform(format, args);
return *this;
}
ostream& ostream::flush()
{
if (_strbuf->sync())
set(ios::badbit);
return *this;
}
ostream& flush(ostream& outs)
{
return outs.flush();
}
istream& ws(istream& ins)
{
if (ins.ipfx1()) {
int ch = skip_ws(ins._strbuf);
if (ch == EOF)
ins.set(ios::eofbit);
else
ins._strbuf->sputbackc(ch);
}
return ins;
}
// Skip white-space. Return 0 on failure (EOF), or 1 on success.
// Differs from ws() manipulator in that failbit is set on EOF.
// Called by ipfx() and ipfx0() if needed.
int istream::_skip_ws()
{
int ch = skip_ws(_strbuf);
if (ch == EOF) {
set(ios::eofbit|ios::failbit);
return 0;
}
else {
_strbuf->sputbackc(ch);
return 1;
}
}
ostream& ends(ostream& outs)
{
outs.put('\0');
return outs;
}
ostream& endl(ostream& outs)
{
return flush(outs.put('\n'));
}
ostream& ostream::write(const char *s, int n)
{
if (opfx()) {
if (_strbuf->sputn(s, n) != n)
set(ios::failbit);
}
return *this;
}
void ostream::do_osfx()
{
if (flags() & ios::unitbuf)
flush();
if (flags() & ios::stdio) {
fflush(stdout);
fflush(stderr);
}
}
iostream::iostream(streambuf* sb, ostream* tied) : ios(sb, tied)
{
_flags |= ios::dont_close;
_gcount = 0;
}
// NOTE: extension for compatibility with old libg++.
// Not really compatible with fistream::close().
#ifdef _STREAM_COMPAT
void ios::close()
{
if (!(_flags & (unsigned int)ios::dont_close))
delete _strbuf;
else if (_strbuf->_flags & _S_IS_FILEBUF)
((struct filebuf*)_strbuf)->close();
else if (_strbuf != NULL)
_strbuf->sync();
_flags |= ios::dont_close;
_strbuf = NULL;
_state = badbit;
}
int istream::skip(int i)
{
int old = (_flags & ios::skipws) != 0;
if (i)
_flags |= ios::skipws;
else
_flags &= ~ios::skipws;
return old;
}
#endif

View File

@ -1,228 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: iostream.h,v 1.2 1993/08/02 17:22:36 mycroft Exp $
#ifndef _IOSTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#define _IOSTREAM_H
#include <streambuf.h>
class istream; class ostream;
typedef ios& (*__manip)(ios&);
typedef istream& (*__imanip)(istream&);
typedef ostream& (*__omanip)(ostream&);
extern istream& ws(istream& ins);
extern ostream& flush(ostream& outs);
extern ostream& endl(ostream& outs);
extern ostream& ends(ostream& outs);
class ostream : virtual public ios
{
// NOTE: If fields are changed, you must fix _fake_ostream in stdstreams.C!
void do_osfx();
public:
ostream() { }
ostream(streambuf* sb, ostream* tied=NULL);
int opfx() {
if (!good()) return 0; else { if (_tie) _tie->flush(); return 1;} }
void osfx() { if (flags() & (ios::unitbuf|ios::stdio))
do_osfx(); }
streambuf* ostreambuf() const { return _strbuf; }
ostream& flush();
ostream& put(char c) { _strbuf->sputc(c); return *this; }
ostream& put(unsigned char c) { return put((char)c); }
ostream& write(const char *s, int n);
ostream& write(const unsigned char *s, int n) { return write((const char*)s, n);}
#ifndef _G_BROKEN_SIGNED_CHAR
ostream& put(signed char c) { return put((char)c); }
ostream& write(const signed char *s, int n) { return write((const char*)s, n);}
#endif
ostream& write(const void *s, int n) { return write((const char*)s, n);}
ostream& seekp(streampos);
ostream& seekp(streamoff, _seek_dir);
streampos tellp();
ostream& form(const char *format ...);
ostream& vform(const char *format, _G_va_list args);
ostream& operator<<(char c);
ostream& operator<<(unsigned char c) { return (*this) << (char)c; }
#ifndef _G_BROKEN_SIGNED_CHAR
ostream& operator<<(signed char c) { return (*this) << (char)c; }
#endif
ostream& operator<<(const char *s);
ostream& operator<<(const unsigned char *s)
{ return (*this) << (const char*)s; }
#ifndef _G_BROKEN_SIGNED_CHAR
ostream& operator<<(const signed char *s)
{ return (*this) << (const char*)s; }
#endif
ostream& operator<<(const void *p);
ostream& operator<<(int n);
ostream& operator<<(unsigned int n);
ostream& operator<<(long n);
ostream& operator<<(unsigned long n);
#ifdef __GNUG__
ostream& operator<<(long long n);
ostream& operator<<(unsigned long long n);
#endif
ostream& operator<<(short n) {return operator<<((int)n);}
ostream& operator<<(unsigned short n) {return operator<<((unsigned int)n);}
ostream& operator<<(double n);
ostream& operator<<(float n) { return operator<<((double)n); }
ostream& operator<<(__omanip func) { return (*func)(*this); }
ostream& operator<<(__manip func) {(*func)(*this); return *this;}
ostream& operator<<(streambuf*);
};
class istream : virtual public ios
{
// NOTE: If fields are changed, you must fix _fake_istream in stdstreams.C!
_G_ssize_t _gcount;
int _skip_ws();
public:
istream() { _gcount = 0; }
istream(streambuf* sb, ostream*tied=NULL);
streambuf* istreambuf() const { return _strbuf; }
istream& get(char* ptr, int len, char delim = '\n');
istream& get(unsigned char* ptr, int len, char delim = '\n')
{ return get((char*)ptr, len, delim); }
istream& get(char& c);
istream& get(unsigned char& c) { return get((char&)c); }
istream& getline(char* ptr, int len, char delim = '\n');
istream& getline(unsigned char* ptr, int len, char delim = '\n')
{ return getline((char*)ptr, len, delim); }
#ifndef _G_BROKEN_SIGNED_CHAR
istream& get(signed char& c) { return get((char&)c); }
istream& get(signed char* ptr, int len, char delim = '\n')
{ return get((char*)ptr, len, delim); }
istream& getline(signed char* ptr, int len, char delim = '\n')
{ return getline((char*)ptr, len, delim); }
#endif
istream& read(char *ptr, int n);
istream& read(unsigned char *ptr, int n) { return read((char*)ptr, n); }
#ifndef _G_BROKEN_SIGNED_CHAR
istream& read(signed char *ptr, int n) { return read((char*)ptr, n); }
#endif
istream& read(void *ptr, int n) { return read((char*)ptr, n); }
istream& get(streambuf& sb, char delim = '\n');
istream& gets(char **s, char delim = '\n');
int ipfx(int need) {
if (!good()) { set(ios::failbit); return 0; }
else {
if (_tie && (need == 0 || rdbuf()->in_avail() < need)) _tie->flush();
if (!need && (flags() & ios::skipws)) return _skip_ws();
else return 1;
}
}
int ipfx0() { // Optimized version of ipfx(0).
if (!good()) { set(ios::failbit); return 0; }
else {
if (_tie) _tie->flush();
if (flags() & ios::skipws) return _skip_ws();
else return 1;
}
}
int ipfx1() { // Optimized version of ipfx(1).
if (!good()) { set(ios::failbit); return 0; }
else {
if (_tie && rdbuf()->in_avail() == 0) _tie->flush();
return 1;
}
}
void isfx() { }
int get() { if (!ipfx1()) return EOF;
else { int ch = _strbuf->sbumpc();
if (ch == EOF) set(ios::eofbit);
return ch;
} }
int peek();
_G_ssize_t gcount() { return _gcount; }
istream& ignore(int n=1, int delim = EOF);
istream& seekg(streampos);
istream& seekg(streamoff, _seek_dir);
streampos tellg();
istream& putback(char ch) {
if (good() && _strbuf->sputbackc(ch) == EOF) clear(ios::badbit);
return *this;}
istream& unget() {
if (good() && _strbuf->sungetc() == EOF) clear(ios::badbit);
return *this;}
istream& scan(const char *format ...);
istream& vscan(const char *format, _G_va_list args);
#ifdef _STREAM_COMPAT
istream& unget(char ch) { return putback(ch); }
int skip(int i);
#endif
istream& operator>>(char*);
istream& operator>>(unsigned char* p) { return operator>>((char*)p); }
#ifndef _G_BROKEN_SIGNED_CHAR
istream& operator>>(signed char*p) { return operator>>((char*)p); }
#endif
istream& operator>>(char& c);
istream& operator>>(unsigned char& c) {return operator>>((char&)c);}
#ifndef _G_BROKEN_SIGNED_CHAR
istream& operator>>(signed char& c) {return operator>>((char&)c);}
#endif
istream& operator>>(int&);
istream& operator>>(long&);
#ifdef __GNUG__
istream& operator>>(long long&);
#endif
istream& operator>>(short&);
istream& operator>>(unsigned int&);
istream& operator>>(unsigned long&);
#ifdef __GNUG__
istream& operator>>(unsigned long long&);
#endif
istream& operator>>(unsigned short&);
istream& operator>>(float&);
istream& operator>>(double&);
istream& operator>>( __manip func) {(*func)(*this); return *this;}
istream& operator>>(__imanip func) { return (*func)(*this); }
istream& operator>>(streambuf*);
};
class iostream : public istream, public ostream
{
_G_ssize_t _gcount;
public:
iostream() { _gcount = 0; }
iostream(streambuf* sb, ostream*tied=NULL);
};
extern istream cin;
extern ostream cout, cerr, clog; // clog->rdbuf() == cerr->rdbuf()
struct Iostream_init { } ; // Compatibility hack for AT&T library.
inline ios& dec(ios& i)
{ i.setf(ios::dec, ios::dec|ios::hex|ios::oct); return i; }
inline ios& hex(ios& i)
{ i.setf(ios::hex, ios::dec|ios::hex|ios::oct); return i; }
inline ios& oct(ios& i)
{ i.setf(ios::oct, ios::dec|ios::hex|ios::oct); return i; }
#endif /*!_IOSTREAM_H*/

View File

@ -1,71 +0,0 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
// Modified for GNU iostream by Per Bothner 1991.
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include "ioprivate.h"
#include "fstream.h"
#include <sys/types.h>
#include <sys/stat.h>
/*
* Allocate a file buffer, or switch to unbuffered I/O.
* Per the ANSI C standard, ALL tty devices default to line buffered.
*
* As a side effect, we set __SOPT or __SNPT (en/dis-able fseek
* optimisation) right after the _fstat() that finds the buffer size.
*/
int filebuf::doallocate()
{
register size_t size, couldbetty;
register char *p;
struct stat st;
if (fd() < 0 || _fstat(fd(), &st) < 0) {
couldbetty = 0;
size = _G_BUFSIZ;
#if 0
/* do not try to optimise fseek() */
fp->_flags |= __SNPT;
#endif
} else {
couldbetty = S_ISCHR(st.st_mode);
#if _G_HAVE_ST_BLKSIZE
size = st.st_blksize <= 0 ? _G_BUFSIZ : st.st_blksize;
#else
size = _G_BUFSIZ;
#endif
}
#ifdef USE_MALLOC_BUF
if ((p = malloc(size)) == NULL) {
unbuffered(1);
// fp->_bf._base = fp->_p = fp->_nbuf;
// fp->_bf._size = 1;
return EOF;
}
#else
p = ALLOC_BUF(size);
#endif
setb(p, p+size, 1);
if (couldbetty && _isatty(fd()))
_flags |= _S_LINE_BUF;
return 1;
}

View File

@ -1,183 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.h"
// Format floating-point number and print them.
// Return number of chars printed, or EOF on error.
// sign_mode == '+' : print "-" or "+"
// sign_mode == ' ' : print "-" or " "
// sign_mode == '\0' : print "-' or ""
int __outfloat(double value, streambuf *sb, char type,
int width, int precision, ios::fmtflags flags,
char sign_mode, char fill)
{
int count = 0;
#define PUT(x) do {if (sb->sputc(x) < 0) goto error; count++;} while (0)
#define PUTN(p, n) \
do {int _n=n; count+=_n; if (sb->sputn(p,_n) != _n) goto error;} while(0)
#define PADN(fill, n) \
do {int _n = n; count+=_n; if (sb->padn(fill, _n) < 0) goto error;} while (0)
ios::fmtflags pad_kind = flags & (ios::left|ios::right|ios::internal);
int skip_zeroes = 0;
int show_dot = (flags & ios::showpoint) != 0;
int decpt;
int sign;
int mode;
#define EBUF_SIZE 12
#define EBUF_END &ebuf[EBUF_SIZE]
char ebuf[EBUF_SIZE];
char *end;
int exp = 0;
switch (type) {
case 'f':
mode = 3;
break;
case 'e':
case 'E':
exp = type;
mode = 2;
if (precision != 999)
precision++; // Add one to include digit before decimal point.
break;
case 'g':
case 'G':
exp = type == 'g' ? 'e' : 'E';
if (precision == 0) precision = 1;
if (!(flags & ios::showpoint))
skip_zeroes = 1;
type = 'g';
mode = 2;
break;
}
/* Do the actual convension */
if (precision == 999 && mode != 3)
mode = 0;
char *p = dtoa(value, mode, precision, &decpt, &sign, &end);
register int i;
int useful_digits = end-p;
char *exponent_start = EBUF_END;
if (mode == 0)
precision = useful_digits;
// Check if we need to emit an exponent.
if (mode != 3 && decpt != 9999) {
i = decpt - 1;
if ((type != 'g' && type != 'F') || i < -4 || i >= precision) {
// Print the exponent into ebuf.
// We write ebuf in reverse order (right-to-left).
char sign;
if (i >= 0)
sign = '+';
else
sign = '-', i = -i;
/* Note: ANSI requires at least 2 exponent digits. */
do {
*--exponent_start = (i % 10) + '0';
i /= 10;
} while (i >= 10);
*--exponent_start = i + '0';
*--exponent_start = sign;
*--exponent_start = exp;
}
}
int exponent_size = EBUF_END - exponent_start;
if (mode == 1)
precision = 1;
/* If we print an exponent, always show just one digit before point. */
if (exponent_size)
decpt = 1;
if (decpt == 9999) { // Infinity or NaN
decpt = useful_digits;
precision = 0;
show_dot = 0;
}
// dtoa truncates trailing zeroes. Set the variable trailing_zeroes to
// the number of 0's we have to add (after the decimal point).
int trailing_zeroes = 0;
if (skip_zeroes)
trailing_zeroes = 0;
else if (type == 'f')
trailing_zeroes = useful_digits <= decpt ? precision
: precision-(useful_digits-decpt);
else if (exponent_size) // 'e' 'E' or 'g' format using exponential notation.
trailing_zeroes = precision - useful_digits;
else // 'g' format not using exponential notation.
trailing_zeroes = useful_digits <= decpt ? precision - decpt
: precision-useful_digits;
if (trailing_zeroes < 0) trailing_zeroes = 0;
if (trailing_zeroes != 0 || useful_digits > decpt)
show_dot = 1;
int print_sign;
if (sign_mode == 0)
print_sign = sign ? '-' : 0;
else if (sign_mode == '+')
print_sign = sign ? '-' : '+';
else /* if (sign_mode == ' ') */
print_sign = sign ? '-' : ' ';
// Calculate the width (before padding).
int unpadded_width =
(print_sign != 0) + trailing_zeroes + exponent_size + show_dot
+ useful_digits
+ (decpt > useful_digits ? decpt - useful_digits
: decpt > 0 ? 0 : 1 - decpt);
int padding = width > unpadded_width ? width - unpadded_width : 0;
if (padding > 0
&& pad_kind != (ios::fmtflags)ios::left
&& pad_kind != (ios::fmtflags)ios::internal) // Default (right) adjust.
PADN(fill, padding);
if (print_sign)
PUT(print_sign);
if (pad_kind == (ios::fmtflags)ios::internal && padding > 0)
PADN(fill, padding);
if (decpt > 0) {
if (useful_digits >= decpt)
PUTN(p, decpt);
else {
PUTN(p, useful_digits);
PADN('0', decpt-useful_digits);
}
if (show_dot) {
PUT('.');
// Print digits after the decimal point.
if (useful_digits > decpt)
PUTN(p + decpt, useful_digits-decpt);
}
}
else {
PUT('0');
if (show_dot) {
PUT('.');
PADN('0', -decpt);
// Print digits after the decimal point.
PUTN(p, useful_digits);
}
}
PADN('0', trailing_zeroes);
if (exponent_size)
PUTN(exponent_start, exponent_size);
if (pad_kind == (ios::fmtflags)ios::left && padding > 0) // Left adjustment
PADN(fill, padding);
return count;
error:
return EOF;
}

View File

@ -1,307 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#include "ioprivate.h"
#include "parsestream.h"
streambuf* parsebuf::setbuf(char*, int)
{
return NULL;
}
int parsebuf::tell_in_line()
{
return 0;
}
int parsebuf::pbackfail(int c)
{
if (c == EOF)
return 0;
if (seekoff(-1, ios::cur) == EOF)
return EOF;
return (unsigned char)c;
}
char* parsebuf::current_line() { return NULL; }
streampos parsebuf::seekoff(streamoff offset, _seek_dir dir, int)
{
// Make offset relative to line start.
switch (dir) {
case ios::beg:
offset -= pos_at_line_start;
break;
case ios::cur:
offset += tell_in_line();
break;
default:
return EOF;
}
if (offset < -1)
return EOF;
if (offset > _line_length + 1)
return EOF;
return seek_in_line(offset) + pos_at_line_start;
}
// string_parsebuf invariants:
// The reserve ares (base() .. ebuf()) is always the entire string.
// The get area (eback() .. egptr()) is the extended current line
// (i.e. with the '\n' at either end, if these exist).
string_parsebuf::string_parsebuf(char *buf, int len,
int delete_at_close /* = 0*/)
: parsebuf()
{
setb(buf, buf+len, delete_at_close);
register char *ptr = buf;
while (ptr < ebuf() && *ptr != '\n') ptr++;
_line_length = ptr - buf;
setg(buf, buf, ptr);
}
int string_parsebuf::underflow()
{
register char* ptr = egptr(); // Point to end of current_line
do {
int i = right() - ptr;
if (i <= 0)
return EOF;
ptr++; i--; // Skip '\n'.
char *line_start = ptr;
while (ptr < right() && *ptr == '\n') ptr++;
setg(line_start-1, line_start, ptr + (ptr < right()));
pos_at_line_start = line_start - left();
_line_length = ptr - line_start;
__line_number++;
} while (gptr() == ptr);
return *gptr();
}
char* string_parsebuf::current_line()
{
char *ptr = eback();
if (__line_number > 0)
ptr++; // Skip '\n' at end of previous line.
return ptr;
}
int string_parsebuf::tell_in_line()
{
int offset = gptr() - eback();
if (__line_number > 0)
offset--;
return offset;
}
int string_parsebuf::seek_in_line(int i)
{
int delta = i - tell_in_line();
gbump(delta); // FIXME: Needs error (bounds) checking!
return i;
}
static const char NewLine[1] = { '\n' };
general_parsebuf::general_parsebuf(streambuf *buf, int delete_arg_buf)
: parsebuf()
{
delete_buf = delete_arg_buf;
sbuf = buf;
int buf_size = 128;
char* buffer = ALLOC_BUF(buf_size);
setb(buffer, buffer+buf_size, 1);
// setg(buffer, buffer, buffer);
}
general_parsebuf::~general_parsebuf()
{
if (delete_buf)
delete sbuf;
}
int general_parsebuf::underflow()
{
register char *ptr = base();
int has_newline = eback() < gptr() && gptr()[-1] == '\n';
if (has_newline)
*ptr++ = '\n';
register streambuf *sb = sbuf;
register int ch;
for (;;) {
ch = sb->sbumpc();
if (ch == EOF)
break;
if (ptr == ebuf()) {
int old_size = ebuf() - base();
char *new_buffer = new char[old_size * 2];
memcpy(new_buffer, base(), old_size);
setb(new_buffer, new_buffer + 2 * old_size, 1);
ptr = new_buffer + old_size;
}
*ptr++ = ch;
if (ch == '\n')
break;
}
char *cur_pos = base() + has_newline;
pos_at_line_start += _line_length + 1;
_line_length = ptr - cur_pos;
if (ch != EOF || _line_length > 0)
__line_number++;
setg(base(), cur_pos, ptr);
return ptr == cur_pos ? EOF : cur_pos[0];
}
char* general_parsebuf::current_line()
{
char* ret = base();
if (__line_number > 1)
ret++; // Move past '\n' from end of previous line.
return ret;
}
int general_parsebuf::tell_in_line()
{
int off = gptr() - base();
if (__line_number > 1)
off--; // Subtract 1 for '\n' from end of previous line.
return off;
}
int general_parsebuf::seek_in_line(int i)
{
if (__line_number == 0)
(void)general_parsebuf::underflow();
if (__line_number > 1)
i++; // Add 1 for '\n' from end of previous line.
if (i < 0) i = 0;
int len = egptr() - eback();
if (i > len) i = len;
setg(base(), base() + i, egptr());
return i;
}
func_parsebuf::func_parsebuf(CharReader func, void *argm) : parsebuf()
{
read_func = func;
arg = argm;
buf_start = NULL;
buf_end = NULL;
setb((char*)NewLine, (char*)NewLine+1, 0);
setg((char*)NewLine, (char*)NewLine+1, (char*)NewLine+1);
backed_up_to_newline = 0;
}
int func_parsebuf::tell_in_line()
{
if (buf_start == NULL)
return 0;
if (egptr() != (char*)NewLine+1)
// Get buffer was line buffer.
return gptr() - buf_start;
if (backed_up_to_newline)
return -1; // Get buffer is '\n' preceding current line.
// Get buffer is '\n' following current line.
return (buf_end - buf_start) + (gptr() - (char*)NewLine);
}
char* func_parsebuf::current_line()
{
return buf_start;
}
int func_parsebuf::seek_in_line(int i)
{
if (i < 0) {
// Back up to preceding '\n'.
if (i < -1) i = -1;
backed_up_to_newline = 1;
setg((char*)NewLine, (char*)NewLine+(i+1), (char*)NewLine+1);
return i;
}
backed_up_to_newline = 0;
int line_length = buf_end-buf_start;
if (i <= line_length) {
setg(buf_start, buf_start+i, buf_end);
return i;
}
i -= line_length;
if (i > 0) i = 1;
setg((char*)NewLine, (char*)NewLine+i, (char*)NewLine+1);
return line_length + i;
}
int func_parsebuf::underflow()
{
retry:
if (gptr() < egptr())
return *gptr();
if (gptr() != (char*)NewLine+1) {
// Get buffer was line buffer. Move to following '\n'.
setg((char*)NewLine, (char*)NewLine, (char*)NewLine+1);
return *gptr();
}
if (backed_up_to_newline)
// Get buffer was '\n' preceding current line. Move to current line.
backed_up_to_newline = 0;
else {
// Get buffer was '\n' following current line. Read new line.
if (buf_start) free(buf_start);
char *str = (*read_func)(arg);
buf_start = str;
if (str == NULL)
return EOF;
// Initially, _line_length == -1, so pos_at_line_start becomes 0.
pos_at_line_start += _line_length + 1;
_line_length = strlen(str);
buf_end = str + _line_length;
__line_number++;
}
setg(buf_start, buf_start, buf_end);
goto retry;
}
#if 0
size_t parsebuf::line_length()
{
if (current_line_length == (size_t)(-1)) // Initial value;
(void)sgetc();
return current_line_length;
}
#endif
int parsebuf::seek_in_line(int i)
{
#if 1
abort();
return 0; // Suppress warning.
#else
if (i > 0) {
size_t len = line_length();
if ((unsigned)i > len) i = len;
}
else if (i < -1) i = -1;
int new_pos = seekoff(pos_at_line_start + i, ios::beg);
if (new_pos == EOF)
return tell_in_line();
else return new_pos - pos_at_line_start;
#endif
}

View File

@ -1,147 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: parsestream.h,v 1.2 1993/08/02 17:22:37 mycroft Exp $
#ifndef PARSESTREAM_H
#define PARSESTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#include "streambuf.h"
// A parsebuf is a streambuf optimized for scanning text files.
// It keeps track of line and column numbers.
// It is guaranteed to remember the entire current line,
// as well the '\n'-s on either side of it (if they exist).
// You can arbitrarily seek (or unget) within this extended line.
// Other backward seeks are not supported.
// Normal read semantics are supported (and hence istream operators like >>).
class parsebuf : public backupbuf {
protected:
_G_fpos_t pos_at_line_start;
long _line_length;
unsigned long __line_number;
char *buf_start;
char *buf_end;
public:
parsebuf *chain;
// Return column number (raw - don't handle tabs etc).
// Retult can be -1, meaning: at '\n' before current line.
virtual int tell_in_line();
// seek to (raw) column I in current line.
// Result is new (raw) column position - differs from I if unable to seek.
// Seek to -1 tries to seek to before previous LF.
virtual int seek_in_line(int i);
// Note: there is no "current line" initially, until something is read.
// Current line number, starting with 0.
// If tell_in_line()==-1, then line number of next line.
int line_number() { return __line_number; }
// Length of current line, not counting either '\n'.
int line_length() { return _line_length; }
// Current line - not a copy, so file ops may trash it.
virtual char* current_line();
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streambuf* setbuf(char* p, int len);
protected:
parsebuf() : backupbuf() { chain= NULL;
__line_number = 0; pos_at_line_start = 0; _line_length = -1; }
virtual int pbackfail(int c);
};
// A string_parsebuf is a parsebuf whose source is a fixed string.
class string_parsebuf : public parsebuf {
public:
int do_delete;
string_parsebuf(char *str, int len, int delete_at_close=0);
virtual int underflow();
virtual char* current_line();
virtual int seek_in_line(int i);
virtual int tell_in_line();
char *left() const { return base(); }
char *right() const { return ebuf(); }
// streampos seekoff(streamoff, _seek_dir, int);
};
// A func_parsebuf calls a given function to get new input.
// Each call returns an entire NUL-terminated line (without the '\n').
// That line has been allocated with malloc(), not new.
// The interface is tailored to the GNU readline library.
// Example:
// char* DoReadLine(void* arg)
// {
// char *line = readline((char*)arg); /* 'arg' is used as prompt. */
// if line == NULL) { putc('\n', stderr); return NULL; }
// if (line[0] != '\0') add_history(line);
// return line;
// }
// char PromptBuffer[100] = "> ";
// func_parsebuf my_stream(DoReadLine, PromptBuffer);
typedef char *(*CharReader)(void *arg);
class istream;
class func_parsebuf : public parsebuf {
public:
void *arg;
CharReader read_func;
int backed_up_to_newline;
func_parsebuf(CharReader func, void *argm = NULL);
int underflow();
virtual int tell_in_line();
virtual int seek_in_line(int i);
virtual char* current_line();
};
// A general_parsebuf is a parsebuf which gets its input from some
// other streambuf. It explicitly buffers up an entire line.
class general_parsebuf : public parsebuf {
public:
streambuf *sbuf;
int delete_buf; // Delete sbuf when destroying this.
general_parsebuf(streambuf *buf, int delete_arg_buf = 0);
int underflow();
virtual int tell_in_line();
virtual int seek_in_line(int i);
~general_parsebuf();
virtual char* current_line();
};
#if 0
class parsestream : public istream {
streammarker marks[2];
short _first; // of the two marks; either 0 or 1
int _lineno;
int first() { return _first; }
int second() { return 1-_first; }
int line_length() { marks[second].delta(marks[first]); }
int line_length() { marks[second].delta(marks[first]); }
int seek_in_line(int i);
int tell_in_line();
int line_number();
};
#endif
#endif /*!defined(PARSESTREAM_H)*/

View File

@ -1,126 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define _POSIX_SOURCE
#include "ioprivate.h"
#include "procbuf.h"
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#ifndef FORK
#define FORK vfork
#ifndef __NetBSD__
extern "C" _G_pid_t vfork(void);
#else
extern "C" int vfork(void);
#endif
#endif
procbuf::procbuf(const char *command, int mode) : filebuf()
{
open(command, mode);
}
procbuf *procbuf::open(const char *command, int mode)
{
int read_or_write;
if (is_open())
return NULL;
int pipe_fds[2];
int parent_end, child_end;
if (::pipe(pipe_fds) < 0)
return NULL;
if (mode == ios::in) {
parent_end = pipe_fds[0];
child_end = pipe_fds[1];
read_or_write = _S_NO_WRITES;
}
else {
parent_end = pipe_fds[1];
child_end = pipe_fds[0];
read_or_write = _S_NO_READS;
}
_pid = FORK();
if (_pid == 0) {
::close(parent_end);
int child_std_end = mode == ios::in ? 1 : 0;
if (child_end != child_std_end) {
::dup2(child_end, child_std_end);
::close(child_end);
}
::execl("/bin/sh", "sh", "-c", command, NULL);
::_exit(127);
}
::close(child_end);
if (_pid < 0) {
::close(parent_end);
return NULL;
}
_fb._fileno = parent_end;
xsetflags(read_or_write, _S_NO_READS|_S_NO_WRITES);
return this;
}
/* #define USE_SIGMASK */
int procbuf::sys_close()
{
_G_pid_t wait_pid;
int status = filebuf::sys_close();
if (status < 0)
return status;
int wstatus;
#if defined(SIG_BLOCK) && defined(SIG_SETMASK)
sigset_t set, oset;
sigemptyset (&set);
sigaddset (&set, SIGINT);
sigaddset (&set, SIGQUIT);
sigaddset (&set, SIGHUP);
sigprocmask (SIG_BLOCK, &set, &oset);
#else
#ifdef USE_SIGMASK
int mask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP));
#else
typedef void (*void_func)(int);
void_func intsave = (void_func)signal(SIGINT, SIG_IGN);
void_func quitsave = (void_func)signal(SIGQUIT, SIG_IGN);
void_func hupsave = (void_func)signal(SIGHUP, SIG_IGN);
#endif
#endif
while ((wait_pid = wait(&wstatus)) != _pid && wait_pid != -1) { }
#if defined(SIG_BLOCK) && defined(SIG_SETMASK)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
#else
#ifdef USE_SIGMASK
(void) sigsetmask(mask);
#else
signal(SIGINT, intsave);
signal(SIGQUIT, quitsave);
signal(SIGHUP, hupsave);
#endif
#endif
if (wait_pid == -1)
return -1;
return 0;
}
procbuf::~procbuf()
{
close();
}

View File

@ -1,31 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: procbuf.h,v 1.2 1993/08/02 17:22:38 mycroft Exp $
#include <streambuf.h>
class procbuf : public filebuf {
_G_pid_t _pid;
public:
procbuf() : filebuf() { }
procbuf(const char *command, int mode);
procbuf* open(const char *command, int mode);
procbuf *close() { return (procbuf*)filebuf::close(); }
virtual int sys_close();
~procbuf();
};

View File

@ -1,856 +0,0 @@
/*
* Copyright (c) 1990 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
/*
* Actual printf innards.
*
* This code is large and complicated...
*/
#include <sys/types.h>
#include "ioprivate.h"
#include <string.h>
#include <stdarg.h>
/*
* Define FLOATING_POINT to get floating point.
*/
#ifndef NO_FLOATING_POINT
#define FLOATING_POINT
#endif
/* end of configuration stuff */
/*
* Helper class and function for `fprintf to unbuffered': creates a
* temporary buffer. We only work on write-only files; this avoids
* worries about ungetc buffers and so forth.
*/
class help_streambuf : public backupbuf {
public:
char *buffer;
int buf_size;
streambuf *sb;
help_streambuf(streambuf *sbuf, char *buf, int n) {
sb = sbuf; buffer = buf; buf_size = n;
setp(buffer, buffer+buf_size); }
~help_streambuf();
virtual int overflow(int c = EOF);
};
int help_streambuf::overflow(int c)
{
int used = pptr() - pbase();
if (used) {
sb->sputn(pbase(), used);
pbump(-used);
}
if (c == EOF || buf_size == 0)
return sb->overflow(c);
return sputc(c);
}
help_streambuf::~help_streambuf()
{
int used = pptr() - pbase();
if (used) {
sb->sputn(pbase(), used);
pbump(-used);
}
}
int help_vform(streambuf *sb, char const *fmt0, va_list ap)
{
char buf[_G_BUFSIZ];
help_streambuf helper(sb, buf, _G_BUFSIZ);
return helper.vform(fmt0, ap);
}
#ifdef FLOATING_POINT
#include "floatio.h"
#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
#define DEFPREC 6
extern "C" double modf(double, double*);
#else /* no FLOATING_POINT */
#define BUF 40
#endif /* FLOATING_POINT */
/*
* Macros for converting digits to letters and vice versa
*/
#define to_digit(c) ((c) - '0')
#define is_digit(c) ((unsigned)to_digit(c) <= 9)
#define to_char(n) ((n) + '0')
/*
* Flags used during conversion.
*/
#define LONGINT 0x01 /* long integer */
#define LONGDBL 0x02 /* long double; unimplemented */
#define SHORTINT 0x04 /* short integer */
#define ALT 0x08 /* alternate form */
#define LADJUST 0x10 /* left adjustment */
#define ZEROPAD 0x20 /* zero (as opposed to blank) pad */
#define HEXPREFIX 0x40 /* add 0x or 0X prefix */
int streambuf::vform(char const *fmt0, _G_va_list ap)
{
register const char *fmt; /* format string */
register int ch; /* character from fmt */
register int n; /* handy integer (short term usage) */
register char *cp; /* handy char pointer (short term usage) */
const char *fmark; /* for remembering a place in fmt */
register int flags; /* flags as above */
int ret; /* return value accumulator */
int width; /* width from format (%8d), or 0 */
int prec; /* precision from format (%.3d), or -1 */
char sign; /* sign prefix (' ', '+', '-', or \0) */
#ifdef FLOATING_POINT
int softsign; /* temporary negative sign for floats */
double _double; /* double precision arguments %[eEfgG] */
#ifndef USE_DTOA
int fpprec; /* `extra' floating precision in [eEfgG] */
#endif
#endif
unsigned long _ulong; /* integer arguments %[diouxX] */
enum { OCT, DEC, HEX } base;/* base for [diouxX] conversion */
int dprec; /* a copy of prec if [diouxX], 0 otherwise */
int dpad; /* extra 0 padding needed for integers */
int fieldsz; /* field size expanded by sign, dpad etc */
// The initialization of 'size' is to suppress a warning that
// 'size' might be used unitialized. It seems gcc can't
// quite grok this spaghetti code ...
int size = 0; /* size of converted field or string */
char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
char ox[2]; /* space for 0x hex-prefix */
/*
* Choose PADSIZE to trade efficiency vs size. If larger
* printf fields occur frequently, increase PADSIZE (and make
* the initialisers below longer).
*/
#define PADSIZE 16 /* pad chunk size */
static char const blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static char const zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
/*
* BEWARE, these `goto error' on error, and PAD uses `n'.
*/
#define PRINT(ptr, len) \
do { if (sputn(ptr, len) != len) goto error; } while (0)
#if 1
#define PAD_SP(howmany) if (padn(' ', howmany) < 0) goto error;
#define PAD_0(howmany) if (padn('0', howmany) < 0) goto error;
#else
#define PAD(howmany, with) { \
if ((n = (howmany)) > 0) { \
while (n > PADSIZE) { \
PRINT(with, PADSIZE); \
n -= PADSIZE; \
} \
PRINT(with, n); \
} \
}
#define PAD_SP(howmany) PAD(howmany, blanks)
#define PAD_0(howmany) PAD(howmany, zeroes)
#endif
/*
* To extend shorts properly, we need both signed and unsigned
* argument extraction methods.
*/
#define SARG() \
(flags&LONGINT ? va_arg(ap, long) : \
flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
(long)va_arg(ap, int))
#define UARG() \
(flags&LONGINT ? va_arg(ap, unsigned long) : \
flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \
(unsigned long)va_arg(ap, unsigned int))
/* optimise cerr (and other unbuffered Unix files) */
if (unbuffered())
return help_vform(this, fmt0, ap);
fmt = fmt0;
ret = 0;
/*
* Scan the format for conversions (`%' character).
*/
for (;;) {
for (fmark = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
/* void */;
if ((n = fmt - fmark) != 0) {
PRINT(fmark, n);
ret += n;
}
if (ch == '\0')
goto done;
fmt++; /* skip over '%' */
flags = 0;
dprec = 0;
#if defined(FLOATING_POINT) && !defined (USE_DTOA)
fpprec = 0;
#endif
width = 0;
prec = -1;
sign = '\0';
rflag: ch = *fmt++;
reswitch: switch (ch) {
case ' ':
/*
* ``If the space and + flags both appear, the space
* flag will be ignored.''
* -- ANSI X3J11
*/
if (!sign)
sign = ' ';
goto rflag;
case '#':
flags |= ALT;
goto rflag;
case '*':
/*
* ``A negative field width argument is taken as a
* - flag followed by a positive field width.''
* -- ANSI X3J11
* They don't exclude field widths read from args.
*/
if ((width = va_arg(ap, int)) >= 0)
goto rflag;
width = -width;
/* FALLTHROUGH */
case '-':
flags |= LADJUST;
flags &= ~ZEROPAD; /* '-' disables '0' */
goto rflag;
case '+':
sign = '+';
goto rflag;
case '.':
if ((ch = *fmt++) == '*') {
n = va_arg(ap, int);
prec = n < 0 ? -1 : n;
goto rflag;
}
n = 0;
while (is_digit(ch)) {
n = 10 * n + to_digit(ch);
ch = *fmt++;
}
prec = n < 0 ? -1 : n;
goto reswitch;
case '0':
/*
* ``Note that 0 is taken as a flag, not as the
* beginning of a field width.''
* -- ANSI X3J11
*/
if (!(flags & LADJUST))
flags |= ZEROPAD; /* '-' disables '0' */
goto rflag;
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
n = 0;
do {
n = 10 * n + to_digit(ch);
ch = *fmt++;
} while (is_digit(ch));
width = n;
goto reswitch;
#ifdef FLOATING_POINT
case 'L':
flags |= LONGDBL;
goto rflag;
#endif
case 'h':
flags |= SHORTINT;
goto rflag;
case 'l':
flags |= LONGINT;
goto rflag;
case 'c':
*(cp = buf) = va_arg(ap, int);
size = 1;
sign = '\0';
break;
case 'D':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'd':
case 'i':
_ulong = SARG();
if ((long)_ulong < 0) {
_ulong = -_ulong;
sign = '-';
}
base = DEC;
goto number;
#ifdef FLOATING_POINT
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
_double = va_arg(ap, double);
#ifdef USE_DTOA
{
ios::fmtflags fmt_flags = 0;
int fill = ' ';
if (flags & ALT)
fmt_flags |= ios::showpoint;
if (flags & LADJUST)
fmt_flags |= ios::left;
else if (flags & ZEROPAD)
fmt_flags |= ios::internal, fill = '0';
n = __outfloat(_double, this, ch, width,
prec < 0 ? DEFPREC : prec,
fmt_flags, sign, fill);
if (n < 0)
goto error;
ret += n;
}
// CHECK ERROR!
continue;
#else
/*
* don't do unrealistic precision; just pad it with
* zeroes later, so buffer size stays rational.
*/
if (prec > MAXFRACT) {
if ((ch != 'g' && ch != 'G') || (flags&ALT))
fpprec = prec - MAXFRACT;
prec = MAXFRACT;
} else if (prec == -1)
prec = DEFPREC;
// __cvt_double may have to round up before the
// "start" of its buffer, i.e.
// ``intf("%.2f", (double)9.999);'';
// if the first character is still NUL, it did.
// softsign avoids negative 0 if _double < 0 but
// no significant digits will be shown.
cp = buf;
*cp = '\0';
size = __cvt_double(_double, prec, flags, &softsign,
ch, cp, buf + sizeof(buf));
if (softsign)
sign = '-';
if (*cp == '\0')
cp++;
break;
#endif
#endif /* FLOATING_POINT */
case 'n':
if (flags & LONGINT)
*va_arg(ap, long *) = ret;
else if (flags & SHORTINT)
*va_arg(ap, short *) = ret;
else
*va_arg(ap, int *) = ret;
continue; /* no output */
case 'O':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'o':
_ulong = UARG();
base = OCT;
goto nosign;
case 'p':
/*
* ``The argument shall be a pointer to void. The
* value of the pointer is converted to a sequence
* of printable characters, in an implementation-
* defined manner.''
* -- ANSI X3J11
*/
/* NOSTRICT */
_ulong = (unsigned long)va_arg(ap, void *);
base = HEX;
flags |= HEXPREFIX;
ch = 'x';
goto nosign;
case 's':
if ((cp = va_arg(ap, char *)) == NULL)
cp = "(null)";
if (prec >= 0) {
/*
* can't use strlen; can only look for the
* NUL in the first `prec' characters, and
* strlen() will go further.
*/
char *p = (char*)memchr(cp, 0, prec);
if (p != NULL) {
size = p - cp;
if (size > prec)
size = prec;
} else
size = prec;
} else
size = strlen(cp);
sign = '\0';
break;
case 'U':
flags |= LONGINT;
/*FALLTHROUGH*/
case 'u':
_ulong = UARG();
base = DEC;
goto nosign;
case 'X':
case 'x':
_ulong = UARG();
base = HEX;
/* leading 0x/X only if non-zero */
if (flags & ALT && _ulong != 0)
flags |= HEXPREFIX;
/* unsigned conversions */
nosign: sign = '\0';
/*
* ``... diouXx conversions ... if a precision is
* specified, the 0 flag will be ignored.''
* -- ANSI X3J11
*/
number: if ((dprec = prec) >= 0)
flags &= ~ZEROPAD;
/*
* ``The result of converting a zero value with an
* explicit precision of zero is no characters.''
* -- ANSI X3J11
*/
cp = buf + BUF;
if (_ulong != 0 || prec != 0) {
char *xdigs; /* digits for [xX] conversion */
/*
* unsigned mod is hard, and unsigned mod
* by a constant is easier than that by
* a variable; hence this switch.
*/
switch (base) {
case OCT:
do {
*--cp = to_char(_ulong & 7);
_ulong >>= 3;
} while (_ulong);
/* handle octal leading 0 */
if (flags & ALT && *cp != '0')
*--cp = '0';
break;
case DEC:
/* many numbers are 1 digit */
while (_ulong >= 10) {
*--cp = to_char(_ulong % 10);
_ulong /= 10;
}
*--cp = to_char(_ulong);
break;
case HEX:
if (ch == 'X')
xdigs = "0123456789ABCDEF";
else /* ch == 'x' || ch == 'p' */
xdigs = "0123456789abcdef";
do {
*--cp = xdigs[_ulong & 15];
_ulong >>= 4;
} while (_ulong);
break;
default:
cp = "bug in vform: bad base";
goto skipsize;
}
}
size = buf + BUF - cp;
skipsize:
break;
default: /* "%?" prints ?, unless ? is NUL */
if (ch == '\0')
goto done;
/* pretend it was %c with argument ch */
cp = buf;
*cp = ch;
size = 1;
sign = '\0';
break;
}
/*
* All reasonable formats wind up here. At this point,
* `cp' points to a string which (if not flags&LADJUST)
* should be padded out to `width' places. If
* flags&ZEROPAD, it should first be prefixed by any
* sign or other prefix; otherwise, it should be blank
* padded before the prefix is emitted. After any
* left-hand padding and prefixing, emit zeroes
* required by a decimal [diouxX] precision, then print
* the string proper, then emit zeroes required by any
* leftover floating precision; finally, if LADJUST,
* pad with blanks.
*/
/*
* compute actual size, so we know how much to pad.
*/
#if defined(FLOATING_POINT) && !defined (USE_DTOA)
fieldsz = size + fpprec;
#else
fieldsz = size;
#endif
dpad = dprec - size;
if (dpad < 0)
dpad = 0;
if (sign)
fieldsz++;
else if (flags & HEXPREFIX)
fieldsz += 2;
fieldsz += dpad;
/* right-adjusting blank padding */
if ((flags & (LADJUST|ZEROPAD)) == 0)
PAD_SP(width - fieldsz);
/* prefix */
if (sign) {
PRINT(&sign, 1);
} else if (flags & HEXPREFIX) {
ox[0] = '0';
ox[1] = ch;
PRINT(ox, 2);
}
/* right-adjusting zero padding */
if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
PAD_0(width - fieldsz);
/* leading zeroes from decimal precision */
PAD_0(dpad);
/* the string or number proper */
PRINT(cp, size);
#if defined(FLOATING_POINT) && !defined (USE_DTOA)
/* trailing f.p. zeroes */
PAD_0(fpprec);
#endif
/* left-adjusting padding (always blank) */
if (flags & LADJUST)
PAD_SP(width - fieldsz);
/* finally, adjust ret */
ret += width > fieldsz ? width : fieldsz;
}
done:
return ret;
error:
return EOF;
/* NOTREACHED */
}
#if defined(FLOATING_POINT) && !defined(USE_DTOA)
static char *exponent(register char *p, register int exp, int fmtch)
{
register char *t;
char expbuf[MAXEXP];
*p++ = fmtch;
if (exp < 0) {
exp = -exp;
*p++ = '-';
}
else
*p++ = '+';
t = expbuf + MAXEXP;
if (exp > 9) {
do {
*--t = to_char(exp % 10);
} while ((exp /= 10) > 9);
*--t = to_char(exp);
for (; t < expbuf + MAXEXP; *p++ = *t++);
}
else {
*p++ = '0';
*p++ = to_char(exp);
}
return (p);
}
static char * round(double fract, int *exp,
register char *start, register char *end,
char ch, int *signp)
{
double tmp;
if (fract)
(void)modf(fract * 10, &tmp);
else
tmp = to_digit(ch);
if (tmp > 4)
for (;; --end) {
if (*end == '.')
--end;
if (++*end <= '9')
break;
*end = '0';
if (end == start) {
if (exp) { /* e/E; increment exponent */
*end = '1';
++*exp;
}
else { /* f; add extra digit */
*--end = '1';
--start;
}
break;
}
}
/* ``"%.3f", (double)-0.0004'' gives you a negative 0. */
else if (*signp == '-')
for (;; --end) {
if (*end == '.')
--end;
if (*end != '0')
break;
if (end == start)
*signp = 0;
}
return (start);
}
int __cvt_double(double number, register int prec, int flags, int *signp,
int fmtch, char *startp, char *endp)
{
register char *p, *t;
register double fract;
int dotrim = 0, expcnt, gformat = 0;
double integer, tmp;
expcnt = 0;
if (number < 0) {
number = -number;
*signp = '-';
} else
*signp = 0;
fract = modf(number, &integer);
/* get an extra slot for rounding. */
t = ++startp;
/*
* get integer portion of number; put into the end of the buffer; the
* .01 is added for modf(356.0 / 10, &integer) returning .59999999...
*/
for (p = endp - 1; integer; ++expcnt) {
tmp = modf(integer / 10, &integer);
*p-- = to_char((int)((tmp + .01) * 10));
}
switch (fmtch) {
case 'f':
case 'F':
/* reverse integer into beginning of buffer */
if (expcnt)
for (; ++p < endp; *t++ = *p);
else
*t++ = '0';
/*
* if precision required or alternate flag set, add in a
* decimal point.
*/
if (prec || flags&ALT)
*t++ = '.';
/* if requires more precision and some fraction left */
if (fract) {
if (prec)
do {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
} while (--prec && fract);
if (fract)
startp = round(fract, (int *)NULL, startp,
t - 1, (char)0, signp);
}
for (; prec--; *t++ = '0');
break;
case 'e':
case 'E':
eformat: if (expcnt) {
*t++ = *++p;
if (prec || flags&ALT)
*t++ = '.';
/* if requires more precision and some integer left */
for (; prec && ++p < endp; --prec)
*t++ = *p;
/*
* if done precision and more of the integer component,
* round using it; adjust fract so we don't re-round
* later.
*/
if (!prec && ++p < endp) {
fract = 0;
startp = round((double)0, &expcnt, startp,
t - 1, *p, signp);
}
/* adjust expcnt for digit in front of decimal */
--expcnt;
}
/* until first fractional digit, decrement exponent */
else if (fract) {
/* adjust expcnt for digit in front of decimal */
for (expcnt = -1;; --expcnt) {
fract = modf(fract * 10, &tmp);
if (tmp)
break;
}
*t++ = to_char((int)tmp);
if (prec || flags&ALT)
*t++ = '.';
}
else {
*t++ = '0';
if (prec || flags&ALT)
*t++ = '.';
}
/* if requires more precision and some fraction left */
if (fract) {
if (prec)
do {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
} while (--prec && fract);
if (fract)
startp = round(fract, &expcnt, startp,
t - 1, (char)0, signp);
}
/* if requires more precision */
for (; prec--; *t++ = '0');
/* unless alternate flag, trim any g/G format trailing 0's */
if (gformat && !(flags&ALT)) {
while (t > startp && *--t == '0');
if (*t == '.')
--t;
++t;
}
t = exponent(t, expcnt, fmtch);
break;
case 'g':
case 'G':
/* a precision of 0 is treated as a precision of 1. */
if (!prec)
++prec;
/*
* ``The style used depends on the value converted; style e
* will be used only if the exponent resulting from the
* conversion is less than -4 or greater than the precision.''
* -- ANSI X3J11
*/
if (expcnt > prec || (!expcnt && fract && fract < .0001)) {
/*
* g/G format counts "significant digits, not digits of
* precision; for the e/E format, this just causes an
* off-by-one problem, i.e. g/G considers the digit
* before the decimal point significant and e/E doesn't
* count it as precision.
*/
--prec;
fmtch -= 2; /* G->E, g->e */
gformat = 1;
goto eformat;
}
/*
* reverse integer into beginning of buffer,
* note, decrement precision
*/
if (expcnt)
for (; ++p < endp; *t++ = *p, --prec);
else
*t++ = '0';
/*
* if precision required or alternate flag set, add in a
* decimal point. If no digits yet, add in leading 0.
*/
if (prec || flags&ALT) {
dotrim = 1;
*t++ = '.';
}
else
dotrim = 0;
/* if requires more precision and some fraction left */
if (fract) {
if (prec) {
/* If no integer part, don't count initial
* zeros as significant digits. */
do {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
} while(!tmp && !expcnt);
while (--prec && fract) {
fract = modf(fract * 10, &tmp);
*t++ = to_char((int)tmp);
}
}
if (fract)
startp = round(fract, (int *)NULL, startp,
t - 1, (char)0, signp);
}
/* alternate format, adds 0's for precision, else trim 0's */
if (flags&ALT)
for (; prec--; *t++ = '0');
else if (dotrim) {
while (t > startp && *--t == '0');
if (*t != '.')
++t;
}
}
return (t - startp);
}
#endif /* defined(FLOATING_POINT) && !defined(USE_DTOA) */
int streambuf::form(char const *format ...)
{
va_list ap;
va_start(ap, format);
int count = vform(format, ap);
va_end(ap);
return count;
}

View File

@ -1,746 +0,0 @@
/*
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
// Extensively hacked for GNU iostream by Per Bothner 1991, 1992.
// Changes copyright Per Bothner 1992.
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "%W% (Berkeley) %G%";
#endif /* LIBC_SCCS and not lint */
#include <ioprivate.h>
#include <ctype.h>
#ifndef NO_STDARG
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#ifndef NO_FLOATING_POINT
#define FLOATING_POINT
#endif
#ifdef FLOATING_POINT
#include "floatio.h"
#define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
#else
#define BUF 40
#endif
/*
* Flags used during conversion.
*/
#define LONG 0x01 /* l: long or double */
#define LONGDBL 0x02 /* L: long double; unimplemented */
#define SHORT 0x04 /* h: short */
#define SUPPRESS 0x08 /* suppress assignment */
#define POINTER 0x10 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x20 /* do not skip blanks */
/*
* The following are used in numeric conversions only:
* SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/
#define SIGNOK 0x40 /* +/- is (still) legal */
#define NDIGITS 0x80 /* no digits detected */
#define DPTOK 0x100 /* (float) decimal point is still legal */
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
#define PFXOK 0x100 /* 0x prefix is (still) legal */
#define NZDIGITS 0x200 /* no zero digits detected */
/*
* Conversion types.
*/
#define CT_CHAR 0 /* %c conversion */
#define CT_CCL 1 /* %[...] conversion */
#define CT_STRING 2 /* %s conversion */
#define CT_INT 3 /* integer, i.e., strtol or strtoul */
#define CT_FLOAT 4 /* floating, i.e., strtod */
#define u_char unsigned char
#define u_long unsigned long
extern "C" u_long strtoul(const char*, char**, int);
static const u_char *__sccl(register char *tab, register const u_char *fmt);
// If state is non-NULL, set failbit and/or eofbit as appropriate.
int streambuf::vscan(char const *fmt0,
_G_va_list ap,
ios *stream /* = NULL */)
{
register const u_char *fmt = (const u_char *)fmt0;
register int c; /* character from format, or conversion */
register size_t width; /* field width, or 0 */
register char *p; /* points into all kinds of strings */
register int n; /* handy integer */
register int flags; /* flags as defined above */
register char *p0; /* saves original value of p when necessary */
int nassigned; /* number of fields assigned */
int nread; /* number of characters consumed from fp */
// Assignments to base and ccfn are just to suppress warnings from gcc.
int base = 0; /* base argument to strtol/strtoul */
typedef u_long (*strtoulfn)(const char*, char**, int);
strtoulfn ccfn = 0;
// conversion function (strtol/strtoul)
char ccltab[256]; /* character class table for %[...] */
char buf[BUF]; /* buffer for numeric conversions */
int seen_eof = 0;
/* `basefix' is used to avoid `if' tests in the integer scanner */
static short basefix[17] =
{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
nassigned = 0;
nread = 0;
for (;;) {
c = *fmt++;
if (c == 0)
goto done;
if (isspace(c)) {
for (;;) {
c = sbumpc();
if (c == EOF)
goto eof_failure;
if (!isspace(c)) {
sputbackc(c);
break;
}
nread++;
}
continue;
}
if (c != '%')
goto literal;
width = 0;
flags = 0;
/*
* switch on the format. continue if done;
* break once format type is derived.
*/
again: c = *fmt++;
switch (c) {
case '%':
literal:
n = sbumpc();
if (n == EOF)
goto eof_failure;
if (n != c) {
sputbackc(n);
goto match_failure;
}
nread++;
continue;
case '*':
flags |= SUPPRESS;
goto again;
case 'l':
flags |= LONG;
goto again;
case 'L':
flags |= LONGDBL;
goto again;
case 'h':
flags |= SHORT;
goto again;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
width = width * 10 + c - '0';
goto again;
/*
* Conversions.
* Those marked `compat' are for 4.[123]BSD compatibility.
*
* (According to ANSI, E and X formats are supposed
* to the same as e and x. Sorry about that.)
*/
case 'D': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'd':
c = CT_INT;
ccfn = (strtoulfn)strtol;
base = 10;
break;
case 'i':
c = CT_INT;
ccfn = (strtoulfn)strtol;
base = 0;
break;
case 'O': /* compat */
flags |= LONG;
/* FALLTHROUGH */
case 'o':
c = CT_INT;
ccfn = strtoul;
base = 8;
break;
case 'u':
c = CT_INT;
ccfn = strtoul;
base = 10;
break;
case 'X':
case 'x':
flags |= PFXOK; /* enable 0x prefixing */
c = CT_INT;
ccfn = strtoul;
base = 16;
break;
#ifdef FLOATING_POINT
case 'E': case 'F':
case 'e': case 'f': case 'g':
c = CT_FLOAT;
break;
#endif
case 's':
c = CT_STRING;
break;
case '[':
fmt = __sccl(ccltab, fmt);
flags |= NOSKIP;
c = CT_CCL;
break;
case 'c':
flags |= NOSKIP;
c = CT_CHAR;
break;
case 'p': /* pointer format is like hex */
flags |= POINTER | PFXOK;
c = CT_INT;
ccfn = strtoul;
base = 16;
break;
case 'n':
if (flags & SUPPRESS) /* ??? */
continue;
if (flags & SHORT)
*va_arg(ap, short *) = nread;
else if (flags & LONG)
*va_arg(ap, long *) = nread;
else
*va_arg(ap, int *) = nread;
continue;
/*
* Disgusting backwards compatibility hacks. XXX
*/
case '\0': /* compat */
nassigned = EOF;
goto done;
default: /* compat */
if (isupper(c))
flags |= LONG;
c = CT_INT;
ccfn = (strtoulfn)strtol;
base = 10;
break;
}
/*
* We have a conversion that requires input.
*/
if (sgetc() == EOF)
goto eof_failure;
/*
* Consume leading white space, except for formats
* that suppress this.
*/
if ((flags & NOSKIP) == 0) {
n = (unsigned char)*_gptr;
while (isspace(n)) {
_gptr++;
nread++;
n = sgetc();
if (n == EOF)
goto eof_failure;
}
// Note that there is at least one character in
// the buffer, so conversions that do not set NOSKIP
// can no longer result in an input failure.
}
/*
* Do the conversion.
*/
switch (c) {
case CT_CHAR:
/* scan arbitrary characters (sets NOSKIP) */
if (width == 0) // FIXME!
width = 1;
if (flags & SUPPRESS) {
size_t sum = 0;
for (;;) {
if ((n = _egptr - _gptr) < (int)width) {
sum += n;
width -= n;
_gptr += n;
if (underflow() == EOF)
if (sum == 0)
goto eof_failure;
else {
seen_eof++;
break;
}
} else {
sum += width;
_gptr += width;
break;
}
}
nread += sum;
} else {
size_t r = sgetn((char*)va_arg(ap, char*),
width);
if (r != width)
goto eof_failure;
nread += r;
nassigned++;
}
break;
case CT_CCL:
/* scan a (nonempty) character class (sets NOSKIP) */
if (width == 0)
width = ~0; /* `infinity' */
/* take only those things in the class */
if (flags & SUPPRESS) {
n = 0;
while (ccltab[(unsigned char)*_gptr]) {
n++, _gptr++;
if (--width == 0)
break;
if (sgetc() == EOF) {
if (n == 0)
goto eof_failure;
seen_eof++;
break;
}
}
if (n == 0)
goto match_failure;
} else {
p0 = p = va_arg(ap, char *);
while (ccltab[(unsigned char)*_gptr]) {
*p++ = *_gptr++;
if (--width == 0)
break;
if (sgetc() == EOF) {
if (p == p0)
goto eof_failure;
seen_eof++;
break;
}
}
n = p - p0;
if (n == 0)
goto match_failure;
*p = 0;
nassigned++;
}
nread += n;
break;
case CT_STRING:
/* like CCL, but zero-length string OK, & no NOSKIP */
if (width == 0)
width = ~0;
if (flags & SUPPRESS) {
n = 0;
while (!isspace((unsigned char)*_gptr)) {
n++, _gptr++;
if (--width == 0)
break;
if (sgetc() == EOF) {
seen_eof++;
break;
}
}
nread += n;
} else {
p0 = p = va_arg(ap, char *);
while (!isspace((unsigned char)*_gptr)) {
*p++ = *_gptr++;
if (--width == 0)
break;
if (sgetc() == EOF) {
seen_eof++;
break;
}
}
*p = 0;
nread += p - p0;
nassigned++;
}
continue;
case CT_INT:
/* scan an integer as if by strtol/strtoul */
if (width == 0 || width > sizeof(buf) - 1)
width = sizeof(buf) - 1;
flags |= SIGNOK | NDIGITS | NZDIGITS;
for (p = buf; width; width--) {
c = (unsigned char)*_gptr;
/*
* Switch on the character; `goto ok'
* if we accept it as a part of number.
*/
switch (c) {
/*
* The digit 0 is always legal, but is
* special. For %i conversions, if no
* digits (zero or nonzero) have been
* scanned (only signs), we will have
* base==0. In that case, we should set
* it to 8 and enable 0x prefixing.
* Also, if we have not scanned zero digits
* before this, do not turn off prefixing
* (someone else will turn it off if we
* have scanned any nonzero digits).
*/
case '0':
if (base == 0) {
base = 8;
flags |= PFXOK;
}
if (flags & NZDIGITS)
flags &= ~(SIGNOK|NZDIGITS|NDIGITS);
else
flags &= ~(SIGNOK|PFXOK|NDIGITS);
goto ok;
/* 1 through 7 always legal */
case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
base = basefix[base];
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* digits 8 and 9 ok iff decimal or hex */
case '8': case '9':
base = basefix[base];
if (base <= 8)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* letters ok iff hex */
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
/* no need to fix base here */
if (base <= 10)
break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS);
goto ok;
/* sign ok only as first character */
case '+': case '-':
if (flags & SIGNOK) {
flags &= ~SIGNOK;
goto ok;
}
break;
/* x ok iff flag still set & 2nd char */
case 'x': case 'X':
if (flags & PFXOK && p == buf + 1) {
base = 16; /* if %i */
flags &= ~PFXOK;
goto ok;
}
break;
}
/*
* If we got here, c is not a legal character
* for a number. Stop accumulating digits.
*/
break;
ok:
/*
* c is legal: store it and look at the next.
*/
*p++ = c;
_gptr++;
if (sgetc() == EOF) {
seen_eof++;
break; /* EOF */
}
}
/*
* If we had only a sign, it is no good; push
* back the sign. If the number ends in `x',
* it was [sign] '0' 'x', so push back the x
* and treat it as [sign] '0'.
*/
if (flags & NDIGITS) {
if (p > buf)
(void) sputbackc(*(u_char *)--p);
goto match_failure;
}
c = ((u_char *)p)[-1];
if (c == 'x' || c == 'X') {
--p;
(void) sputbackc(c);
}
if ((flags & SUPPRESS) == 0) {
u_long res;
*p = 0;
res = (*ccfn)(buf, (char **)NULL, base);
if (flags & POINTER)
*va_arg(ap, void **) = (void *)res;
else if (flags & SHORT)
*va_arg(ap, short *) = res;
else if (flags & LONG)
*va_arg(ap, long *) = res;
else
*va_arg(ap, int *) = res;
nassigned++;
}
nread += p - buf;
break;
#ifdef FLOATING_POINT
case CT_FLOAT:
/* scan a floating point number as if by strtod */
if (width == 0 || width > sizeof(buf) - 1)
width = sizeof(buf) - 1;
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
for (p = buf; width; width--) {
c = (unsigned char)*_gptr;
/*
* This code mimicks the integer conversion
* code, but is much simpler.
*/
switch (c) {
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
case '8': case '9':
flags &= ~(SIGNOK | NDIGITS);
goto fok;
case '+': case '-':
if (flags & SIGNOK) {
flags &= ~SIGNOK;
goto fok;
}
break;
case '.':
if (flags & DPTOK) {
flags &= ~(SIGNOK | DPTOK);
goto fok;
}
break;
case 'e': case 'E':
/* no exponent without some digits */
if ((flags&(NDIGITS|EXPOK)) == EXPOK) {
flags =
(flags & ~(EXPOK|DPTOK)) |
SIGNOK | NDIGITS;
goto fok;
}
break;
}
break;
fok:
*p++ = c;
_gptr++;
if (sgetc() == EOF) {
seen_eof++;
break; /* EOF */
}
}
/*
* If no digits, might be missing exponent digits
* (just give back the exponent) or might be missing
* regular digits, but had sign and/or decimal point.
*/
if (flags & NDIGITS) {
if (flags & EXPOK) {
/* no digits at all */
while (p > buf)
sputbackc(*(u_char *)--p);
goto match_failure;
}
/* just a bad exponent (e and maybe sign) */
c = *(u_char *)--p;
if (c != 'e' && c != 'E') {
(void)sputbackc(c);/* sign */
c = *(u_char *)--p;
}
(void) sputbackc(c);
}
if ((flags & SUPPRESS) == 0) {
double res;
*p = 0;
#ifdef USE_DTOA
res = strtod(buf, NULL);
#else
res = atof(buf);
#endif
if (flags & LONG)
*va_arg(ap, double *) = res;
else
*va_arg(ap, float *) = res;
nassigned++;
}
nread += p - buf;
break;
#endif /* FLOATING_POINT */
}
}
eof_failure:
seen_eof++;
input_failure:
if (nassigned == 0)
nassigned = -1;
match_failure:
if (stream)
stream->set(ios::failbit);
done:
if (stream && seen_eof)
stream->set(ios::eofbit);
return (nassigned);
}
/*
* Fill in the given table from the scanset at the given format
* (just after `['). Return a pointer to the character past the
* closing `]'. The table has a 1 wherever characters should be
* considered part of the scanset.
*/
static const u_char *__sccl(register char *tab, register const u_char *fmt)
{
register int c, n, v;
/* first `clear' the whole table */
c = *fmt++; /* first char hat => negated scanset */
if (c == '^') {
v = 1; /* default => accept */
c = *fmt++; /* get new first char */
} else
v = 0; /* default => reject */
/* should probably use memset here */
for (n = 0; n < 256; n++)
tab[n] = v;
if (c == 0)
return (fmt - 1);/* format ended before closing ] */
/*
* Now set the entries corresponding to the actual scanset
* to the opposite of the above.
*
* The first character may be ']' (or '-') without being special;
* the last character may be '-'.
*/
v = 1 - v;
for (;;) {
tab[c] = v; /* take character c */
doswitch:
n = *fmt++; /* and examine the next */
switch (n) {
case 0: /* format ended too soon */
return (fmt - 1);
case '-':
/*
* A scanset of the form
* [01+-]
* is defined as `the digit 0, the digit 1,
* the character +, the character -', but
* the effect of a scanset such as
* [a-zA-Z0-9]
* is implementation defined. The V7 Unix
* scanf treats `a-z' as `the letters a through
* z', but treats `a-a' as `the letter a, the
* character -, and the letter a'.
*
* For compatibility, the `-' is not considerd
* to define a range if the character following
* it is either a close bracket (required by ANSI)
* or is not numerically greater than the character
* we just stored in the table (c).
*/
n = *fmt;
if (n == ']' || n < c) {
c = '-';
break; /* resume the for(;;) */
}
fmt++;
do { /* fill in the range */
tab[++c] = v;
} while (c < n);
#if 1 /* XXX another disgusting compatibility hack */
/*
* Alas, the V7 Unix scanf also treats formats
* such as [a-c-e] as `the letters a through e'.
* This too is permitted by the standard....
*/
goto doswitch;
#else
c = *fmt++;
if (c == 0)
return (fmt - 1);
if (c == ']')
return (fmt);
#endif
break;
case ']': /* end of scanset */
return (fmt);
default: /* just another character */
c = n;
break;
}
}
/* NOTREACHED */
}
int streambuf::scan(char const *format ...)
{
va_list ap;
va_start(ap, format);
int count = vscan(format, ap);
va_end(ap);
return count;
}

View File

@ -1,64 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.h"
// Algorithm based on that used by Berkeley pre-4.4 fgets implementation.
// Read chars into buf (of size n), until delim is seen.
// Return number of chars read (at most n-1).
// If extract_delim < 0, leave delimiter unread.
// If extract_delim > 0, insert delim in output.
long streambuf::sgetline(char* buf, size_t n, char delim, int extract_delim)
{
register char *ptr = buf;
if (n <= 0)
return EOF;
n--; // Leave space for final '\0'.
do {
int len = egptr() - gptr();
if (len <= 0)
if (underflow() == EOF)
break;
else
len = egptr() - gptr();
if (len >= (int)n)
len = n;
char *t = (char*)memchr((void*)_gptr, delim, len);
if (t != NULL) {
size_t old_len = ptr-buf;
len = t - _gptr;
if (extract_delim >= 0) {
t++;
old_len++;
if (extract_delim > 0)
len++;
}
memcpy((void*)ptr, (void*)_gptr, len);
ptr[len] = 0;
_gptr = t;
return old_len + len;
}
memcpy((void*)ptr, (void*)_gptr, len);
_gptr += len;
ptr += len;
n -= len;
} while (n != 0);
*ptr = 0;
return ptr - buf;
}

View File

@ -1,112 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#include <stdiostream.h>
// A stdiobuf is "tied" to a FILE object (as used by the stdio package).
// Thus a stdiobuf is always synchronized with the corresponding FILE,
// though at the cost of some overhead. (If you use the implementation
// of stdio supplied with this library, you don't need stdiobufs.)
// This implementation inherits from filebuf, but implement the virtual
// functions sys_read/..., using the stdio functions fread/... instead
// of the low-level read/... system calls. This has the advantage that
// we get all of the nice filebuf semantics automatically, though
// with some overhead.
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef SEEK_END
#define SEEK_END 2
#endif
stdiobuf::stdiobuf(FILE *f) : filebuf(fileno(f))
{
_file = f;
// Turn off buffer in stdiobuf. Instead, rely on buffering in (FILE).
// Thus the stdiobuf will be synchronized with the FILE.
setbuf(NULL, 0);
}
_G_ssize_t stdiobuf::sys_read(char* buf, size_t size)
{
return fread(buf, 1, size, _file);
}
_G_ssize_t stdiobuf::sys_write(const void *buf, long n)
{
_G_ssize_t count = fwrite(buf, 1, n, _file);
if (_fb._offset >= 0)
_fb._offset += n;
return count;
}
_G_fpos_t stdiobuf::sys_seek(_G_fpos_t offset, _seek_dir dir)
{
// Normally, equivalent to: fdir=dir
int fdir =
(dir == ios::beg) ? SEEK_SET :
(dir == ios::cur) ? SEEK_CUR :
(dir == ios::end) ? SEEK_END :
dir;
return fseek(_file, offset, fdir);
}
int stdiobuf::sys_close()
{
int status = fclose(_file);
_file = NULL;
return status;
}
int stdiobuf::sync()
{
if (filebuf::sync() == EOF)
return EOF;
if (!(xflags() & _S_NO_WRITES))
if (fflush(_file))
return EOF;
#if 0
// This loses when writing to a pipe.
if (fseek(_file, 0, SEEK_CUR) == EOF)
return EOF;
#endif
return 0;
}
int stdiobuf::overflow(int c /* = EOF*/)
{
if (filebuf::overflow(c) == EOF)
return EOF;
if (c != EOF)
return c;
return fflush(_file);
}
int stdiobuf::xsputn(const char* s, int n)
{
// The filebuf implementation of sputn loses.
return streambuf::xsputn(s, n);
}

View File

@ -1,45 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: stdiostream.h,v 1.2 1993/08/02 17:22:39 mycroft Exp $
#ifndef _STDIOSTREAM_H
#define _STDIOSTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#include <streambuf.h>
#include <stdio.h>
class stdiobuf : public filebuf {
protected:
FILE *_file;
public:
FILE* stdiofile() const { return _file; }
stdiobuf(FILE *f);
virtual _G_ssize_t sys_read(char* buf, _G_size_t size);
virtual _G_fpos_t sys_seek(_G_fpos_t, _seek_dir);
virtual _G_ssize_t sys_write(const void*, long);
virtual int sys_close();
virtual int sync();
virtual int overflow(int c = EOF);
virtual int xsputn(const char* s, int n);
};
#endif /* !_STDIOSTREAM_H */

View File

@ -1,129 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.h"
#include <stdio.h>
// This file defines the standard streambufs, corresponding to cin, cout, cerr.
// We define two sets:
//
// __std_filebuf_0, __std_filebuf_1, __std_filebuf_2 are filebufs using
// file descriptor 0/1/2.
//
// __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf are stdiostreams
// pointing to stdin, stdout, stderr.
// To avoid problems depending on constructor order (and for
// efficiency) the standard streambufs (and streams) are
// constructed statically using C-style '{ ... }' initializers.
// Since you're not allowed to do this for structs that
// have virtuals, we define fake streambuf and stream classes
// that don't have any C++-isms, and initialize those.
// To initialize the vtable field of the standard filebufs,
// we use the expression 'vt_filebuf' which must evaluate to
// (the address of) the virtual function table for the
// filebuf class.
#if _G_NAMES_HAVE_UNDERSCORE
#define UNDERSCORE "_"
#else
#define UNDERSCORE ""
#endif
// First define the filebuf-based objects.
#if !defined(vt_filebuf)
#ifndef __GNUG__
// This works for cfront.
#define vt_filebuf __vtbl__7filebuf
extern char vt_filebuf[1];
#elif _G_DOLLAR_IN_LABEL
#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5
extern char vt_filebuf[1] asm(UNDERSCORE "_vt$7filebuf");
#else
extern char vt_filebuf[1] asm(UNDERSCORE "_vt$filebuf");
#endif
#else
#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5
extern char vt_filebuf[1] asm(UNDERSCORE "_vt.7filebuf");
#else
extern char vt_filebuf[1] asm(UNDERSCORE "_vt.filebuf");
#endif
#endif
#endif /* !defined(vt_filebuf) */
struct _fake_filebuf {
struct __streambuf s;
char* vtable;
struct __file_fields f;
};
#define FILEBUF_LITERAL(CHAIN, FLAGS) \
{ _IO_MAGIC+_S_LINKED+_S_IS_FILEBUF+_S_IS_BACKUPBUF+FLAGS, \
0, 0, 0, 0, 0, 0, 0, 0, CHAIN, 0, 0, 0, 0, 0}
#define DEF_FILEBUF(NAME, FD, CHAIN, FLAGS) \
_fake_filebuf NAME = {FILEBUF_LITERAL(CHAIN, FLAGS), vt_filebuf, {FD}};
DEF_FILEBUF(__std_filebuf_0, 0, 0, _S_NO_WRITES);
DEF_FILEBUF(__std_filebuf_1, 1, (streambuf*)&__std_filebuf_0, _S_NO_READS);
DEF_FILEBUF(__std_filebuf_2, 2, (streambuf*)&__std_filebuf_1,
_S_NO_READS+_S_UNBUFFERED);
// Nest define the stdiobuf-bases objects.
#if !defined(vt_stdiobuf)
#ifndef __GNUG__
// This works for cfront.
#define vt_stdiobuf __vtbl__8stdiobuf
extern char vt_stdiobuf[1];
#elif _G_DOLLAR_IN_LABEL
#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5
extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt$8stdiobuf");
#else
extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt$stdiobuf");
#endif
#else
#if __GNUC_MAJOR__ > 2 || __GNUC_MINOR__ >= 5
extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt.8stdiobuf");
#else
extern char vt_stdiobuf[1] asm(UNDERSCORE "_vt.stdiobuf");
#endif
#endif
#endif /* !defined(vt_stdiobuf) */
struct _fake_stdiobuf {
struct __streambuf s;
char* vtable;
struct __file_fields f;
FILE *_f;
};
#define DEF_STDIOBUF(NAME, FILE, FD, CHAIN, FLAGS) \
_fake_stdiobuf NAME[1] = {{ \
FILEBUF_LITERAL(CHAIN, (FLAGS)|_S_UNBUFFERED),\
vt_stdiobuf, {FD}, FILE}};
DEF_STDIOBUF(__stdin_stdiobuf, stdin, 0, (streambuf*)&__std_filebuf_2,
_S_NO_WRITES);
DEF_STDIOBUF(__stdout_stdiobuf, stdout, 1, (streambuf*)__stdin_stdiobuf,
_S_NO_READS);
DEF_STDIOBUF(__stderr_stdiobuf, stderr, 2, (streambuf*)__stdout_stdiobuf,
_S_NO_READS);
streambuf* streambuf::_list_all = (streambuf*)__stderr_stdiobuf;

View File

@ -1,145 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include "ioprivate.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 &__std_filebuf_0/&__std_filebuf_1/&__std_filebuf_2.
#ifdef _STDIO_USES_IOSTREAM
#define USE_FILEBUF
#endif
#ifdef NAMES_HAVE_UNDERSCORE
#define UNDERSCORE "_"
#else
#define UNDERSCORE ""
#endif
#ifdef USE_FILEBUF
#define CIN_SBUF __std_filebuf_0
#define COUT_SBUF __std_filebuf_1
#define CERR_SBUF __std_filebuf_2
static int use_stdiobuf = 0;
#else
#define CIN_SBUF __stdin_stdiobuf
#define COUT_SBUF __stdout_stdiobuf
#define CERR_SBUF __stderr_stdiobuf
static int use_stdiobuf = 1;
#endif
struct _fake_filebuf;
extern _fake_filebuf __std_filebuf_0, __std_filebuf_1, __std_filebuf_2;
struct _fake_stdiobuf;
extern _fake_stdiobuf __stdin_stdiobuf, __stdout_stdiobuf, __stderr_stdiobuf;
#define cin CIN
#define cout COUT
#define cerr CERR
#define clog CLOG
#include "iostream.h"
#undef cin
#undef cout
#undef cerr
#undef clog
#ifdef __GNUC__
#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 */
_G_ssize_t _gcount;
#else
/* This is supposedly correct for cfront. */
_G_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];
};
#define STD_STR(SBUF, TIE, EXTRA_FLAGS) \
(streambuf*)&SBUF, TIE, 0, ios::dont_close|ios::skipws|EXTRA_FLAGS, ' ',0,0,6
#ifdef __GNUC__
#define OSTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
TYPE NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
#define ISTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
TYPE NAME = { {&NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
#else
#define OSTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
TYPE NAME = { {0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
#define ISTREAM_DEF(TYPE, NAME, SBUF, TIE, EXTRA_FLAGS) \
TYPE NAME = { {0, 0, &NAME.base}, {STD_STR(SBUF, TIE, EXTRA_FLAGS) }};
#endif
OSTREAM_DEF(_fake_ostream, cout, COUT_SBUF, NULL, 0)
OSTREAM_DEF(_fake_ostream, cerr, CERR_SBUF, (ostream*)&cout, ios::unitbuf)
ISTREAM_DEF(_fake_istream, cin, CIN_SBUF, (ostream*)&cout, 0)
/* Only for (partial) compatibility with AT&T's library. */
OSTREAM_DEF(_fake_ostream, clog, CERR_SBUF, (ostream*)&cout, 0)
// Switches between using __std_filebuf_{0,1,2} and
// __std{in,out,err}_stdiobuf for standard streams. This is
// normally not needed, 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) {
cout.base._strbuf = (streambuf*)&__stdout_stdiobuf;
cin.base._strbuf = (streambuf*)&__stdin_stdiobuf;
cerr.base._strbuf = (streambuf*)&__stderr_stdiobuf;
clog.base._strbuf = (streambuf*)&__stderr_stdiobuf;
} else {
cout.base._strbuf = (streambuf*)&__std_filebuf_1;
cin.base._strbuf = (streambuf*)&__std_filebuf_0;
cerr.base._strbuf = (streambuf*)&__std_filebuf_2;
clog.base._strbuf = (streambuf*)&__std_filebuf_2;
}
int old_state = use_stdiobuf;
use_stdiobuf = new_state;
return old_state;
#endif
}

View File

@ -1,120 +0,0 @@
#include <stdarg.h>
#include "ioprivate.h"
#include "stream.h"
#include "strstream.h"
static char Buffer[_G_BUFSIZ];
#define EndBuffer (Buffer+_G_BUFSIZ)
static char* next_chunk = Buffer; // Start of available part of Buffer.
char* form(const char* format, ...)
{
int space_left = EndBuffer - next_chunk;
// If less that 25% of the space is available start over.
if (space_left < (_G_BUFSIZ>>2))
next_chunk = Buffer;
char* buf = next_chunk;
strstreambuf stream(buf, EndBuffer-buf-1, buf);
va_list ap;
va_start(ap, format);
int count = stream.vform(format, ap);
va_end(ap);
stream.sputc(0);
next_chunk = buf + stream.pcount();
return buf;
}
#define u_long unsigned long
static char* itoa(unsigned long i, int size, int neg, int base)
{
// Conservative estimate: If base==2, might need 8 characters
// for each input byte, but normally 3 is plenty.
int needed = size ? size
: (base >= 8 ? 3 : 8) * sizeof(unsigned long) + 2;
int space_left = EndBuffer - next_chunk;
if (space_left <= needed)
next_chunk = Buffer; // start over.
char* buf = next_chunk;
register char* ptr = buf+needed+1;
next_chunk = ptr;
if (needed < (2+neg) || ptr > EndBuffer)
return NULL;
*--ptr = 0;
if (i == 0)
*--ptr = '0';
while (i != 0 && ptr > buf) {
int ch = i % base;
i = i / base;
if (ch >= 10)
ch += 'a' - 10;
else
ch += '0';
*--ptr = ch;
}
if (neg)
*--ptr = '-';
if (size == 0)
return ptr;
while (ptr > buf)
*--ptr = ' ';
return buf;
}
char* dec(long i, int len /* = 0 */)
{
if (i >= 0) return itoa((unsigned long)i, len, 0, 10);
else return itoa((unsigned long)(-i), len, 1, 10);
}
char* dec(int i, int len /* = 0 */)
{
if (i >= 0) return itoa((unsigned long)i, len, 0, 10);
else return itoa((unsigned long)(-i), len, 1, 10);
}
char* dec(unsigned long i, int len /* = 0 */)
{
return itoa(i, len, 0, 10);
}
char* dec(unsigned int i, int len /* = 0 */)
{
return itoa(i, len, 0, 10);
}
char* hex(long i, int len /* = 0 */)
{
return itoa((unsigned long)i, len, 0, 16);
}
char* hex(int i, int len /* = 0 */)
{
return itoa((unsigned long)i, len, 0, 16);
}
char* hex(unsigned long i, int len /* = 0 */)
{
return itoa(i, len, 0, 16);
}
char* hex(unsigned int i, int len /* = 0 */)
{
return itoa(i, len, 0, 16);
}
char* oct(long i, int len /* = 0 */)
{
return itoa((unsigned long)i, len, 0, 8);
}
char* oct(int i, int len /* = 0 */)
{
return itoa((unsigned long)i, len, 0, 8);
}
char* oct(unsigned long i, int len /* = 0 */)
{
return itoa(i, len, 0, 8);
}
char* oct(unsigned int i, int len /* = 0 */)
{
return itoa(i, len, 0, 8);
}

View File

@ -1,33 +0,0 @@
// $Id: stream.h,v 1.2 1993/08/02 17:22:40 mycroft Exp $
#ifndef _COMPAT_STREAM_H
#define _COMPAT_STREAM_H
// Compatibility with old library.
#define _STREAM_COMPAT
#include <iostream.h>
extern char* form(const char*, ...);
extern char* dec(long, int=0);
extern char* dec(int, int=0);
extern char* dec(unsigned long, int=0);
extern char* dec(unsigned int, int=0);
extern char* hex(long, int=0);
extern char* hex(int, int=0);
extern char* hex(unsigned long, int=0);
extern char* hex(unsigned int, int=0);
extern char* oct(long, int=0);
extern char* oct(int, int=0);
extern char* oct(unsigned long, int=0);
extern char* oct(unsigned int, int=0);
char* chr(char ch, int width = 0);
char* str(const char* s, int width = 0);
inline istream& WS(istream& str) { return ws(str); }
#endif /* !_COMPAT_STREAM_H */

View File

@ -1,666 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991, 1992 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#define _STREAM_COMPAT
#ifdef __GNUG__
#pragma implementation
#endif
#include "ioprivate.h"
#include <string.h>
void streambuf::_un_link()
{
if (_flags & _S_LINKED) {
streambuf **f;
for (f = &_list_all; *f != NULL; f = &(*f)->xchain()) {
if (*f == this) {
*f = xchain();
break;
}
}
_flags &= ~_S_LINKED;
}
}
void streambuf::_link_in()
{
if ((_flags & _S_LINKED) == 0) {
_flags |= _S_LINKED;
xchain() = _list_all;
_list_all = this;
}
}
// Return minimum _pos markers
// Assumes the current get area is the main get area.
int streambuf::_least_marker()
{
int least_so_far = _egptr - _eback;
for (register streammarker *mark = _markers;
mark != NULL; mark = mark->_next)
if (mark->_pos < least_so_far)
least_so_far = mark->_pos;
return least_so_far;
}
// Switch current get area from backup buffer to (start of) main get area.
void streambuf::switch_to_main_get_area()
{
char *tmp;
_flags &= ~_S_IN_BACKUP;
// Swap _egptr and _other_egptr.
tmp= _egptr; _egptr= _other_egptr; _other_egptr= tmp;
// Swap _eback and _other_gbase.
tmp= _eback; _eback = _other_gbase; _other_gbase = tmp;
_gptr = _eback;
}
// Switch current get area from main get area to (end of) backup area.
void streambuf::switch_to_backup_area()
{
char *tmp;
_flags |= _S_IN_BACKUP;
// Swap _egptr and _other_egptr.
tmp = _egptr; _egptr = _other_egptr; _other_egptr = tmp;
// Swap _gbase and _other_gbase.
tmp = _eback; _eback = _other_gbase; _other_gbase = tmp;
_gptr = _egptr;
}
int streambuf::switch_to_get_mode()
{
if (_pptr > _pbase)
if (overflow(EOF) == EOF)
return EOF;
if (in_backup()) {
_eback = _aux_limit;
}
else {
_eback = _base;
if (_pptr > _egptr)
_egptr = _pptr;
}
_gptr = _pptr;
setp(_gptr, _gptr);
_flags &= ~_S_CURRENTLY_PUTTING;
return 0;
}
void streambuf::free_backup_area()
{
if (in_backup())
switch_to_main_get_area(); // Just in case.
delete [] _other_gbase;
_other_gbase = NULL;
_other_egptr = NULL;
_aux_limit = NULL;
}
#if 0
int streambuf::switch_to_put_mode()
{
_pbase = _gptr;
_pptr = _gptr;
_epptr = in_backup() ? _egptr : _ebuf; // wrong if line- or un-buffered?
_gptr = _egptr;
_eback = _egptr;
_flags |= _S_CURRENTLY_PUTTING;
return 0;
}
#endif
#ifdef _G_FRIEND_BUG
int __underflow(register streambuf *sb) { return __UNDERFLOW(sb); }
int __UNDERFLOW(register streambuf *sb)
#else
int __underflow(register streambuf *sb)
#endif
{
if (sb->put_mode())
if (sb->switch_to_get_mode() == EOF) return EOF;
if (sb->_gptr < sb->_egptr)
return *(unsigned char*)sb->_gptr;
if (sb->in_backup()) {
sb->switch_to_main_get_area();
if (sb->_gptr < sb->_egptr)
return *sb->_gptr;
}
if (sb->have_markers()) {
// Append [_gbase.._egptr] to backup area.
int least_mark = sb->_least_marker();
// needed_size is how much space we need in the backup area.
int needed_size = (sb->_egptr - sb->_eback) - least_mark;
int current_Bsize = sb->_other_egptr - sb->_other_gbase;
int avail; // Extra space available for future expansion.
if (needed_size > current_Bsize) {
avail = 0; // 100 ?? FIXME
char *new_buffer = new char[avail+needed_size];
if (least_mark < 0) {
memcpy(new_buffer + avail,
sb->_other_egptr + least_mark,
-least_mark);
memcpy(new_buffer +avail - least_mark,
sb->_eback,
sb->_egptr - sb->_eback);
}
else
memcpy(new_buffer + avail,
sb->_eback + least_mark,
needed_size);
delete [] sb->_other_gbase;
sb->_other_gbase = new_buffer;
sb->_other_egptr = new_buffer + avail + needed_size;
}
else {
avail = current_Bsize - needed_size;
if (least_mark < 0) {
memmove(sb->_other_gbase + avail,
sb->_other_egptr + least_mark,
-least_mark);
memcpy(sb->_other_gbase + avail - least_mark,
sb->_eback,
sb->_egptr - sb->_eback);
}
else if (needed_size > 0)
memcpy(sb->_other_gbase + avail,
sb->_eback + least_mark,
needed_size);
}
// FIXME: Dubious arithmetic if pointers are NULL
sb->_aux_limit = sb->_other_gbase + avail;
// Adjust all the streammarkers.
int delta = sb->_egptr - sb->_eback;
for (register streammarker *mark = sb->_markers;
mark != NULL; mark = mark->_next)
mark->_pos -= delta;
}
else if (sb->have_backup())
sb->free_backup_area();
return sb->underflow();
}
#ifdef _G_FRIEND_BUG
int __overflow(register streambuf *sb, int c) { return __OVERFLOW(sb, c); }
int __OVERFLOW(register streambuf *sb, int c)
#else
int __overflow(streambuf* sb, int c)
#endif
{
return sb->overflow(c);
}
int streambuf::xsputn(register const char* s, int n)
{
if (n <= 0)
return 0;
register int more = n;
for (;;) {
int count = _epptr - _pptr; // Space available.
if (count > 0) {
if (count > more)
count = more;
if (count > 20) {
memcpy(_pptr, s, count);
s += count;
_pptr += count;
}
else if (count <= 0)
count = 0;
else {
register char *p = _pptr;
for (register int i = count; --i >= 0; ) *p++ = *s++;
_pptr = p;
}
more -= count;
}
if (more == 0 || __overflow(this, (unsigned char)*s++) == EOF)
break;
more--;
}
return n - more;
}
int streambuf::padn(char pad, int count)
{
#define PADSIZE 16
static char const blanks[PADSIZE] =
{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
static char const zeroes[PADSIZE] =
{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
char padbuf[PADSIZE];
const char *padptr;
register int i;
if (pad == ' ')
padptr = blanks;
else if (pad == '0')
padptr = zeroes;
else {
for (i = PADSIZE; --i >= 0; ) padbuf[i] = pad;
padptr = padbuf;
}
for (i = count; i >= PADSIZE; i -= PADSIZE)
if (sputn(padptr, PADSIZE) != PADSIZE)
return EOF;
if (i > 0 && sputn(padptr, i) != i)
return EOF;
return pad;
}
int streambuf::xsgetn(char* s, int n)
{
register int more = n;
for (;;) {
int count = _egptr - _gptr; // Data available.
if (count > 0) {
if (count > more)
count = more;
if (count > 20) {
memcpy(s, _gptr, count);
s += count;
_gptr += count;
}
else if (count <= 0)
count = 0;
else {
register char *p = _gptr;
for (register int i = count; --i >= 0; ) *s++ = *p++;
_gptr = p;
}
more -= count;
}
if (more == 0 || __underflow(this) == EOF)
break;
}
return n - more;
}
int streambuf::ignore(int n)
{
register int more = n;
for (;;) {
int count = _egptr - _gptr; // Data available.
if (count > 0) {
if (count > more)
count = more;
_gptr += count;
more -= count;
}
if (more == 0 || __underflow(this) == EOF)
break;
}
return n - more;
}
int streambuf::sync()
{
if (gptr() == egptr() && pptr() == pbase())
return 0;
return EOF;
}
int streambuf::pbackfail(int c)
{
if (_gptr > _eback)
_gptr--;
else if (seekoff(-1, ios::cur, ios::in) == EOF)
return EOF;
if (c != EOF && *_gptr != c)
*_gptr = c;
return (unsigned char)c;
}
streambuf* streambuf::setbuf(char* p, int len)
{
if (sync() == EOF)
return NULL;
if (p == NULL || len == 0) {
unbuffered(1);
setb(_shortbuf, _shortbuf+1, 0);
}
else {
unbuffered(0);
setb(p, p+len, 0);
}
setp(0, 0);
setg(0, 0, 0);
return this;
}
streampos streambuf::seekpos(streampos pos, int mode)
{
return seekoff(pos, ios::beg, mode);
}
void streambuf::setb(char* b, char* eb, int a)
{
if (_base && !(_flags & _S_USER_BUF))
FREE_BUF(_base);
_base = b;
_ebuf = eb;
if (a)
_flags &= ~_S_USER_BUF;
else
_flags |= _S_USER_BUF;
}
int streambuf::doallocate()
{
char *buf = ALLOC_BUF(_G_BUFSIZ);
if (buf == NULL)
return EOF;
setb(buf, buf+_G_BUFSIZ, 1);
return 1;
}
void streambuf::doallocbuf()
{
if (base() || (!unbuffered() && doallocate() != EOF)) return;
setb(_shortbuf, _shortbuf+1, 0);
}
streambuf::streambuf(int flags)
{
_flags = _IO_MAGIC|flags;
_base = NULL;
_ebuf = NULL;
_eback = NULL;
_gptr = NULL;
_egptr = NULL;
_pbase = NULL;
_pptr = NULL;
_epptr = NULL;
_chain = NULL; // Not necessary.
_other_gbase = NULL;
_aux_limit = NULL;
_other_egptr = NULL;
_markers = NULL;
_cur_column = 0;
}
streambuf::~streambuf()
{
if (_base && !(_flags & _S_USER_BUF))
FREE_BUF(_base);
for (register streammarker *mark = _markers;
mark != NULL; mark = mark->_next)
mark->_sbuf = NULL;
}
streampos
streambuf::seekoff(streamoff, _seek_dir, int mode /*=ios::in|ios::out*/)
{
return EOF;
}
int streambuf::sputbackc(char c)
{
if (_gptr > _eback && (unsigned char)_gptr[-1] == (unsigned char)c) {
_gptr--;
return (unsigned char)c;
}
return pbackfail(c);
}
int streambuf::sungetc()
{
if (_gptr > _eback) {
_gptr--;
return (unsigned char)*_gptr;
}
else
return pbackfail(EOF);
}
#if 0 /* Work in progress */
void streambuf::collumn(int c)
{
if (c == -1)
_collumn = -1;
else
_collumn = c - (_pptr - _pbase);
}
#endif
int streambuf::get_column()
{
if (_cur_column)
return __adjust_column(_cur_column - 1, pbase(), pptr() - pbase());
return -1;
}
int streambuf::set_column(int i)
{
_cur_column = i+1;
return 0;
}
int streambuf::flush_all()
{
int result = 0;
for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
if (sb->overflow(EOF) == EOF)
result = EOF;
return result;
}
void streambuf::flush_all_linebuffered()
{
for (streambuf *sb = _list_all; sb != NULL; sb = sb->xchain())
if (sb->linebuffered())
sb->overflow(EOF);
}
int backupbuf::underflow()
{
return EOF;
}
int backupbuf::overflow(int c)
{
return EOF;
}
streammarker::streammarker(streambuf *sb)
{
_sbuf = sb;
if (!(sb->xflags() & _S_IS_BACKUPBUF)) {
set_streampos(sb->seekoff(0, ios::cur, ios::in));
_next = 0;
}
else {
if (sb->put_mode())
sb->switch_to_get_mode();
if (((backupbuf*)sb)->in_backup())
set_offset(sb->_gptr - sb->_egptr);
else
set_offset(sb->_gptr - sb->_eback);
// Should perhaps sort the chain?
_next = ((backupbuf*)sb)->_markers;
((backupbuf*)sb)->_markers = this;
}
}
streammarker::~streammarker()
{
if (saving()) {
// Unlink from sb's chain.
register streammarker **ptr = &((backupbuf*)_sbuf)->_markers;
for (; ; ptr = &(*ptr)->_next)
if (*ptr == NULL)
break;
else if (*ptr == this) {
*ptr = _next;
return;
}
}
#if 0
if _sbuf has a backup area that is no longer needed, should we delete
it now, or wait until underflow()?
#endif
}
#define BAD_DELTA EOF
int streammarker::delta(streammarker& other_mark)
{
if (_sbuf != other_mark._sbuf)
return BAD_DELTA;
if (saving() && other_mark.saving())
return _pos - other_mark._pos;
else if (!saving() && !other_mark.saving())
return _spos - other_mark._spos;
else
return BAD_DELTA;
}
int streammarker::delta()
{
if (_sbuf == NULL)
return BAD_DELTA;
if (saving()) {
int cur_pos;
if (_sbuf->in_backup())
cur_pos = _sbuf->_gptr - _sbuf->_egptr;
else
cur_pos = _sbuf->_gptr - _sbuf->_eback;
return _pos - cur_pos;
}
else {
if (_spos == EOF)
return BAD_DELTA;
int cur_pos = _sbuf->seekoff(0, ios::cur);
if (cur_pos == EOF)
return BAD_DELTA;
return _pos - cur_pos;
}
}
int streambuf::seekmark(streammarker& mark, int delta /* = 0 */)
{
if (mark._sbuf != this)
return EOF;
if (!mark.saving()) {
return seekpos(mark._spos, ios::in);
}
else if (mark._pos >= 0) {
if (in_backup())
switch_to_main_get_area();
_gptr = _eback + mark._pos;
}
else {
if (!in_backup())
switch_to_backup_area();
_gptr = _egptr + mark._pos;
}
return 0;
}
void streambuf::unsave_markers()
{
register streammarker *mark =_markers;
if (_markers) {
streampos offset = seekoff(0, ios::cur, ios::in);
if (offset != EOF) {
offset += eGptr() - Gbase();
for ( ; mark != NULL; mark = mark->_next)
mark->set_streampos(mark->_pos + offset);
}
else {
for ( ; mark != NULL; mark = mark->_next)
mark->set_streampos(EOF);
}
_markers = 0;
}
free_backup_area();
}
int backupbuf::pbackfail(int c)
{
if (_gptr <= _eback) {
// Need to handle a filebuf in write mode (switch to read mode). FIXME!
if (have_backup() && !in_backup()) {
switch_to_backup_area();
}
if (!have_backup()) {
// No backup buffer: allocate one.
// Use short buffer, if unused? (probably not) FIXME
int backup_size = 128;
_other_gbase = new char [backup_size];
_other_egptr = _other_gbase + backup_size;
_aux_limit = _other_egptr;
switch_to_backup_area();
}
else if (gptr() <= eback()) {
// Increase size of existing backup buffer.
size_t new_size;
size_t old_size = egptr() - eback();
new_size = 2 * old_size;
char* new_buf = new char [new_size];
memcpy(new_buf+(new_size-old_size), eback(), old_size);
delete [] eback();
setg(new_buf, new_buf+(new_size-old_size), new_buf+new_size);
_aux_limit = _gptr;
}
}
_gptr--;
if (c != EOF && *_gptr != c)
*_gptr = c;
return (unsigned char)*_gptr;
}
unsigned __adjust_column(unsigned start, const char *line, int count)
{
register const char *ptr = line + count;
while (ptr > line)
if (*--ptr == '\n')
return line + count - ptr - 1;
return start + count;
}
int ios::readable() { return !(rdbuf()->_flags & _S_NO_READS); }
int ios::writable() { return !(rdbuf()->_flags & _S_NO_WRITES); }
int ios::is_open() { return rdbuf()
&& (rdbuf()->_flags & _S_NO_READS+_S_NO_WRITES)
!= _S_NO_READS+_S_NO_WRITES; }
#if defined(linux)
#define IO_CLEANUP ;
#endif
#ifdef IO_CLEANUP
IO_CLEANUP
#else
struct __io_defs {
__io_defs() { }
~__io_defs() { streambuf::flush_all(); }
};
__io_defs io_defs__;
#endif

View File

@ -1,497 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: streambuf.h,v 1.2 1993/08/02 17:22:41 mycroft Exp $
#ifndef _STREAMBUF_H
#define _STREAMBUF_H
#ifdef __GNUG__
#pragma interface
#endif
/* #define _G_IO_THROW */ /* Not implemented: ios::failure */
#include <_G_config.h>
#ifdef _G_NEED_STDARG_H
#include <stdarg.h>
#endif
#ifndef EOF
#define EOF (-1)
#endif
#ifndef NULL
#ifdef __GNUC__
#define NULL ((void*)0)
#else
#define NULL (0)
#endif
#endif
class ostream; class streambuf; class backupbuf;
// In case some header files defines these as macros.
#undef open
#undef close
#ifdef _G_FRIEND_BUG
extern int __UNDERFLOW(streambuf*);
extern int __OVERFLOW(streambuf*, int);
#endif
extern "C" int __underflow(streambuf*);
extern "C" int __overflow(streambuf*, int);
typedef _G_off_t streamoff;
typedef _G_off_t streampos; // Should perhaps be _G_fpos_t ?
typedef unsigned long __fmtflags;
typedef unsigned char __iostate;
struct _ios_fields { // The data members of an ios.
streambuf *_strbuf;
ostream* _tie;
int _width;
__fmtflags _flags;
_G_wchar_t _fill;
__iostate _state;
__iostate _exceptions;
int _precision;
};
#define _IOS_GOOD 0
#define _IOS_EOF 1
#define _IOS_FAIL 2
#define _IOS_BAD 4
#define _IOS_INPUT 1
#define _IOS_OUTPUT 2
#define _IOS_ATEND 4
#define _IOS_APPEND 8
#define _IOS_TRUNC 16
#define _IOS_NOCREATE 32
#define _IOS_NOREPLACE 64
#define _IOS_BIN 128
#ifdef _STREAM_COMPAT
enum state_value {
_good = _IOS_GOOD,
_eof = _IOS_EOF,
_fail = _IOS_FAIL,
_bad = _IOS_BAD };
enum open_mode {
input = _IOS_INPUT,
output = _IOS_OUTPUT,
atend = _IOS_ATEND,
append = _IOS_APPEND };
#endif
class ios : public _ios_fields {
public:
typedef __fmtflags fmtflags;
typedef int iostate;
typedef int openmode;
typedef int streamsize;
enum io_state {
goodbit = _IOS_GOOD,
eofbit = _IOS_EOF,
failbit = _IOS_FAIL,
badbit = _IOS_BAD };
enum open_mode {
in = _IOS_INPUT,
out = _IOS_OUTPUT,
ate = _IOS_ATEND,
app = _IOS_APPEND,
trunc = _IOS_TRUNC,
nocreate = _IOS_NOCREATE,
noreplace = _IOS_NOREPLACE,
bin = _IOS_BIN };
enum seek_dir { beg, cur, end};
// ANSI: typedef enum seek_dir seekdir; etc
enum { skipws=01, left=02, right=04, internal=010,
dec=020, oct=040, hex=0100,
showbase=0200, showpoint=0400, uppercase=01000, showpos=02000,
scientific=04000, fixed=010000, unitbuf=020000, stdio=040000,
dont_close=0100000 //Don't delete streambuf on stream destruction
};
enum { // Masks.
basefield=dec+oct+hex,
floatfield = scientific+fixed,
adjustfield = left+right+internal
};
#ifdef _G_IO_THROW
class failure : public xmsg {
ios* _stream;
public:
failure(ios* stream) { _stream = stream; }
failure(string cause, ios* stream) { _stream = stream; }
ios* rdios() const { return _stream; }
};
#endif
ostream* tie() const { return _tie; }
ostream* tie(ostream* val) { ostream* save=_tie; _tie=val; return save; }
// Methods to change the format state.
_G_wchar_t fill() const { return (_G_wchar_t)_fill; }
_G_wchar_t fill(_G_wchar_t newf)
{_G_wchar_t oldf = (_G_wchar_t)_fill; _fill = (char)newf; return oldf;}
fmtflags flags() const { return _flags; }
fmtflags flags(fmtflags new_val) {
fmtflags old_val = _flags; _flags = new_val; return old_val; }
int precision() const { return _precision; }
int precision(int newp) {
unsigned short oldp = _precision; _precision = (unsigned short)newp;
return oldp; }
fmtflags setf(fmtflags val) {
fmtflags oldbits = _flags;
_flags |= val; return oldbits; }
fmtflags setf(fmtflags val, fmtflags mask) {
fmtflags oldbits = _flags;
_flags = (_flags & ~mask) | (val & mask); return oldbits; }
fmtflags unsetf(fmtflags mask) {
fmtflags oldbits = _flags & mask;
_flags &= ~mask; return oldbits; }
int width() const { return _width; }
int width(int val) { int save = _width; _width = val; return save; }
#ifdef _G_IO_THROW
void _throw_failure() { throw new ios::failure(this); }
#else
void _throw_failure() { }
#endif
streambuf* rdbuf() const { return _strbuf; }
void clear(iostate state = 0) {
_state = _strbuf ? state : state|badbit;
if (_state & _exceptions) _throw_failure(); }
void set(iostate flag) { _state |= flag;
if (_state & _exceptions) _throw_failure(); }
void setstate(iostate flag) { _state |= flag; // ANSI
if (_state & _exceptions) _throw_failure(); }
int good() const { return _state == 0; }
int eof() const { return _state & ios::eofbit; }
int fail() const { return _state & (ios::badbit|ios::failbit); }
int bad() const { return _state & ios::badbit; }
iostate rdstate() const { return _state; }
operator void*() const { return fail() ? (void*)0 : (void*)(-1); }
int operator!() const { return fail(); }
iostate exceptions() const { return _exceptions; }
void exceptions(iostate enable) {
_exceptions = enable;
if (_state & _exceptions) _throw_failure(); }
static int sync_with_stdio(int on);
static void sync_with_stdio() { sync_with_stdio(1); }
#ifdef _STREAM_COMPAT
void unset(state_value flag) { _state &= ~flag; }
void close();
int is_open();
int readable();
int writable();
#endif
// Used to initialize standard streams. Not needed in this implementation.
class Init {
public:
Init () { }
};
protected:
ios(streambuf* sb = 0, ostream* tie = 0);
virtual ~ios();
void init(streambuf* sb) { _state=0; _strbuf=sb; }
};
#if __GNUG__==1
typedef int _seek_dir;
#else
typedef ios::seek_dir _seek_dir;
#endif
// Magic numbers and bits for the _flags field.
// The magic numbers use the high-order bits of _flags;
// the remaining bits are abailable for variable flags.
// Note: The magic numbers must all be negative if stdio
// emulation is desired.
#define _IO_MAGIC 0xFBAD0000 /* Magic number */
#define _OLD_STDIO_MAGIC 0xFABC0000 /* Emulate old stdio. */
#define _IO_MAGIC_MASK 0xFFFF0000
#define _S_USER_BUF 1 /* User owns buffer; don't delete it on close. */
#define _S_UNBUFFERED 2
#define _S_NO_READS 4 /* Reading not allowed */
#define _S_NO_WRITES 8 /* Writing not allowd */
#define _S_EOF_SEEN 0x10
#define _S_ERR_SEEN 0x20
#define _S_DELETE_DONT_CLOSE 0x40
#define _S_LINKED 0x80 // Set if linked (using _chain) to streambuf::_list_all.
#define _S_IN_BACKUP 0x100
#define _S_LINE_BUF 0x200
#define _S_TIED_PUT_GET 0x400 // Set if put and get pointer logicly tied.
#define _S_CURRENTLY_PUTTING 0x800
#define _S_IS_APPENDING 0x1000
#define _S_IS_BACKUPBUF 0x4000
#define _S_IS_FILEBUF 0x8000
// A streammarker remembers a position in a buffer.
// You are guaranteed to be able to seek back to it if it is saving().
class streammarker {
friend class streambuf;
#ifdef _G_FRIEND_BUG
friend int __UNDERFLOW(streambuf*);
#else
friend int __underflow(streambuf*);
#endif
struct streammarker *_next; // Only if saving()
streambuf *_sbuf; // Only valid if saving().
streampos _spos; // -2: means that _pos is valid.
void set_streampos(streampos sp) { _spos = sp; }
void set_offset(int offset) { _pos = offset; _spos = (streampos)(-2); }
// If _pos >= 0, it points to _buf->Gbase()+_pos.
// if _pos < 0, it points to _buf->eBptr()+_pos.
int _pos;
public:
streammarker(streambuf *sb);
~streammarker();
int saving() { return _spos == -2; }
int delta(streammarker&);
int delta();
};
struct __streambuf {
// NOTE: If this is changed, also change __FILE in stdio/stdio.h!
int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
char* _gptr; /* Current get pointer */
char* _egptr; /* End of get area. */
char* _eback; /* Start of putback+get area. */
char* _pbase; /* Start of put area. */
char* _pptr; /* Current put pointer. */
char* _epptr; /* End of put area. */
char* _base; /* Start of reserve area. */
char* _ebuf; /* End of reserve area. */
struct streambuf *_chain;
// The following fields are used to support backing up and undo.
friend class streammarker;
char *_other_gbase; // Pointer to start of non-current get area.
char *_aux_limit; // Pointer to first valid character of backup area,
char *_other_egptr; // Pointer to end of non-current get area.
streammarker *_markers;
#define __HAVE_COLUMN /* temporary */
// 1+column number of pbase(); 0 is unknown.
unsigned short _cur_column;
char _unused;
char _shortbuf[1];
};
extern unsigned __adjust_column(unsigned start, const char *line, int count);
struct streambuf : public __streambuf {
friend class ios;
friend class istream;
friend class ostream;
friend class streammarker;
#ifdef _G_FRIEND_BUG
friend int __UNDERFLOW(streambuf*);
#else
friend int __underflow(streambuf*);
#endif
protected:
static streambuf* _list_all; /* List of open streambufs. */
streambuf*& xchain() { return _chain; }
void _un_link();
void _link_in();
char* gptr() const { return _gptr; }
char* pptr() const { return _pptr; }
char* egptr() const { return _egptr; }
char* epptr() const { return _epptr; }
char* pbase() const { return _pbase; }
char* eback() const { return _eback; }
char* base() const { return _base; }
char* ebuf() const { return _ebuf; }
int blen() const { return _ebuf - _base; }
void xput_char(char c) { *_pptr++ = c; }
int xflags() { return _flags; }
int xflags(int f) { int fl = _flags; _flags = f; return fl; }
void xsetflags(int f) { _flags |= f; }
void xsetflags(int f, int mask) { _flags = (_flags & ~mask) | (f & mask); }
void gbump(int n) { _gptr += n; }
void pbump(int n) { _pptr += n; }
void setb(char* b, char* eb, int a=0);
void setp(char* p, char* ep) { _pbase=_pptr=p; _epptr=ep; }
void setg(char* eb, char* g, char *eg) { _eback=eb; _gptr=g; _egptr=eg; }
char *shortbuf() { return _shortbuf; }
int in_backup() { return _flags & _S_IN_BACKUP; }
// The start of the main get area: FIXME: wrong for write-mode filebuf?
char *Gbase() { return in_backup() ? _other_gbase : _eback; }
// The end of the main get area:
char *eGptr() { return in_backup() ? _other_egptr : _egptr; }
// The start of the backup area:
char *Bbase() { return in_backup() ? _eback : _other_gbase; }
char *Bptr() { return _aux_limit; }
// The end of the backup area:
char *eBptr() { return in_backup() ? _egptr : _other_egptr; }
char *Nbase() { return _other_gbase; }
char *eNptr() { return _other_egptr; }
int have_backup() { return _other_gbase != NULL; }
int have_markers() { return _markers != NULL; }
int _least_marker();
void switch_to_main_get_area();
void switch_to_backup_area();
void free_backup_area();
void unsave_markers(); // Make all streammarkers !saving().
int put_mode() { return _flags & _S_CURRENTLY_PUTTING; }
int switch_to_get_mode();
streambuf(int flags=0);
public:
static int flush_all();
static void flush_all_linebuffered(); // Flush all line buffered files.
virtual int underflow() = 0; // Leave public for now
virtual int overflow(int c = EOF) = 0; // Leave public for now
virtual int doallocate();
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streampos seekpos(streampos pos, int mode = ios::in|ios::out);
int seekmark(streammarker& mark, int delta = 0);
int sputbackc(char c);
int sungetc();
virtual ~streambuf();
int unbuffered() { return _flags & _S_UNBUFFERED ? 1 : 0; }
int linebuffered() { return _flags & _S_LINE_BUF ? 1 : 0; }
void unbuffered(int i)
{ if (i) _flags |= _S_UNBUFFERED; else _flags &= ~_S_UNBUFFERED; }
void linebuffered(int i)
{ if (i) _flags |= _S_LINE_BUF; else _flags &= ~_S_LINE_BUF; }
int allocate() { // For AT&T compatibility
if (base() || unbuffered()) return 0;
else return doallocate(); }
// Allocate a buffer if needed; use _shortbuf if appropriate.
void allocbuf() { if (base() == NULL) doallocbuf(); }
void doallocbuf();
virtual int sync();
virtual int pbackfail(int c);
virtual streambuf* setbuf(char* p, int len);
int in_avail() { return _egptr - _gptr; }
int out_waiting() { return _pptr - _pbase; }
virtual int xsputn(const char* s, int n);
int sputn(const char* s, int n) { return xsputn(s, n); }
int padn(char pad, int n); // Emit 'n' copies of 'pad'.
virtual int xsgetn(char* s, int n);
int sgetn(char* s, int n) { return xsgetn(s, n); }
int ignore(int);
virtual int get_column();
virtual int set_column(int);
long sgetline(char* buf, _G_size_t n, char delim, int putback_delim);
int sbumpc() {
if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
else return *(unsigned char*)_gptr++; }
int sgetc() {
if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
else return *(unsigned char*)_gptr; }
int snextc() {
if (_gptr >= _egptr && __underflow(this) == EOF) return EOF;
else return _gptr++, sgetc(); }
int sputc(int c) {
if (_pptr >= _epptr) return __overflow(this, (unsigned char)c);
else return *_pptr++ = c, (unsigned char)c; }
void stossc() { if (_gptr < _egptr) _gptr++; }
int vscan(char const *fmt0, _G_va_list ap, ios* stream = NULL);
int scan(char const *fmt0 ...);
int vform(char const *fmt0, _G_va_list ap);
int form(char const *fmt0 ...);
#if 0 /* Work in progress */
int collumn(); // Current collumn number (of put pointer). -1 is unknown.
void collumn(int c); // Set collumn number of put pointer to c.
#endif
};
// A backupbuf is a streambuf with full backup and savepoints on reading.
// All standard streambufs in the GNU iostream library are backupbufs.
// A backupbuf may have two get area:
// - The main get area, and (sometimes) the putback area.
// Whichever one of these contains the gptr is the current get area;
// the other one is the non-current get area.
class backupbuf : public streambuf {
friend class streammarker;
protected:
backupbuf(int flags=0) : streambuf(flags|_S_IS_BACKUPBUF) { }
public:
virtual int pbackfail(int c);
virtual int underflow();
virtual int overflow(int c = EOF);
};
struct __file_fields {
short _fileno;
int _blksize;
_G_off_t _offset;
// char* _save_gptr; char* _save_egptr;
};
class filebuf : public backupbuf {
protected:
struct __file_fields _fb;
void init();
public:
static const int openprot; // Non-ANSI AT&T-ism: Default open protection.
filebuf();
filebuf(int fd);
filebuf(int fd, char* p, int len);
~filebuf();
filebuf* attach(int fd);
filebuf* open(const char *filename, const char *mode);
filebuf* open(const char *filename, ios::openmode mode, int prot = 0664);
virtual int underflow();
virtual int overflow(int c = EOF);
int is_open() const { return _fb._fileno >= 0; }
int fd() const { return is_open() ? _fb._fileno : EOF; }
filebuf* close();
virtual int doallocate();
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
virtual streambuf* setbuf(char* p, int len);
int xsputn(const char* s, int n);
int xsgetn(char* s, int n);
virtual int sync();
protected: // See documentation in filebuf.C.
// virtual int pbackfail(int c);
int is_reading() { return eback() != egptr(); }
char* cur_ptr() { return is_reading() ? gptr() : pptr(); }
/* System's idea of pointer */
char* file_ptr() { return eGptr(); }
int do_write(const char *data, int to_do);
int do_flush() { return do_write(_pbase, _pptr-_pbase); }
// Low-level operations (Usually invoke system calls.)
virtual _G_ssize_t sys_read(char* buf, _G_size_t size);
virtual _G_fpos_t sys_seek(_G_fpos_t, _seek_dir);
virtual _G_ssize_t sys_write(const void*, long);
virtual int sys_stat(void*); // Actually, a (struct stat*)
virtual int sys_close();
};
inline ios::ios(streambuf* sb /* = 0 */, ostream* tie_to /* = 0 */) {
_state = sb ? ios::goodbit : ios::badbit; _exceptions=0;
_strbuf=sb; _tie = tie_to; _width=0; _fill=' ';
_flags=ios::skipws|ios::dec; _precision=6; }
inline ios::~ios() {
if (!(_flags & (unsigned int)ios::dont_close)) delete _strbuf; }
#endif /* _STREAMBUF_H */

View File

@ -1,238 +0,0 @@
// This is part of the iostream library, providing input/output for C++.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#ifdef __GNUG__
#pragma implementation
#endif
#include "ioprivate.h"
#include <strstream.h>
static void* default_alloc(_G_size_t size)
{
return (void*)new char[size];
}
static void default_free(void* ptr)
{
delete [] (char*)ptr;
}
istrstream::istrstream(const char *cp, int n)
{
init(new strstreambuf(cp, n));
}
ostrstream::ostrstream()
{
init(new strstreambuf());
}
strstreambase::strstreambase(char *cp, int n, int mode)
{
char *pstart;
if (mode == ios::app || mode == ios::ate)
pstart = cp + strlen(cp);
else
pstart = cp;
init(new strstreambuf(cp, n, pstart));
}
char *strstreambuf::str()
{
freeze(1);
return base();
}
_G_size_t strstreambuf::pcount()
{
_G_size_t put_len = pptr() - pbase();
if (put_len < _len) put_len = _len;
return put_len;
}
int strstreambuf::overflow(int c /* = EOF */)
{
const int flush_only = c == EOF;
if (_flags & _S_NO_WRITES)
return flush_only ? 0 : EOF;
size_t pos = pptr() - pbase();
size_t get_pos = gptr() - pbase();
if (pos > _len) _len = pos;
if (pos >= blen() + flush_only) {
char *new_buf;
size_t new_size = 2 * blen();
if (frozen()) /* not allowed to enlarge */
return EOF;
new_buf = (char*)(*_allocate_buffer)(new_size);
memcpy(new_buf, base(), blen());
if (new_buf == NULL) {
// __ferror(fp) = 1;
return EOF;
}
#if 0
if (lenp == &_len) /* use '\0'-filling */
memset(new_buf + pos, 0, blen() - pos);
#endif
if (_base) {
(*_free_buffer)(_base);
_base = NULL; // So setb() won't try to delete _base.
}
setb(new_buf, new_buf + new_size, 1);
}
setp(base(), ebuf());
pbump(pos);
setg(base(), base() + get_pos, base() + _len);
if (!flush_only) {
*pptr() = (unsigned char) c;
pbump(1);
}
return c;
}
int strstreambuf::underflow()
{
size_t ppos = pptr() - pbase();
if (ppos > _len) _len = ppos;
setg(base(), gptr(), base() + _len);
if (gptr() < egptr())
return *gptr();
else
return EOF;
}
void strstreambuf::init_dynamic(_alloc_type alloc, _free_type free,
int initial_size)
{
_len = 0;
if (initial_size < 16)
initial_size = 16;
_allocate_buffer = alloc ? alloc : default_alloc;
_free_buffer = free ? free : default_free;
char * buf = (char*)(*_allocate_buffer)(initial_size);
setb(buf, buf + initial_size, 1);
setp(buf, buf + initial_size);
setg(buf, buf, buf);
}
void strstreambuf::init_static(char *ptr, int size, char *pstart)
{
if (size == 0)
size = strlen(ptr);
else if (size < 0) {
// If size is negative 'the characters are assumed to
// continue indefinitely.' This is kind of messy ...
#if 1
size = 512;
// Try increasing powers of 2, as long as we don't wrap around.
// This can lose in pathological cases (ptr near the end
// of the address space). A better solution might be to
// adjust the size on underflow/overflow. FIXME.
int s;
for (; s = 2*size, s > 0 && ptr + s > ptr && s < 0x4000000L; )
size = s;
size = s;
#else
// The following semi-portable kludge assumes that
// sizeof(unsigned long) == sizeof(char*). Hence,
// (unsigned long)(-1) should be the largest possible address.
unsigned long highest = (unsigned long)(-1);
// Pointers are signed on some brain-damaged systems, in
// which case we divide by two to get the maximum signed address.
if ((char*)highest < ptr)
highest >>= 1;
size = (char*)highest - ptr;
#endif
}
setb(ptr, ptr+size);
if (pstart) {
setp(ptr, ebuf());
pbump(pstart-ptr);
setg(ptr, ptr, pstart);
}
else {
setp(ptr, ptr);
setg(ptr, ptr, ebuf());
}
_len = egptr() - ptr;
}
void strstreambuf::init_static (const char *ptr, int size)
{
init_static((char*)ptr, size, NULL);
xsetflags(_S_NO_WRITES);
}
strstreambuf::~strstreambuf()
{
if (_base && !(_flags & _S_USER_BUF))
(_free_buffer)(_base);
_base = NULL;
}
streampos strstreambuf::seekoff(streamoff off, _seek_dir dir,
int mode /*=ios::in|ios::out*/)
{
size_t cur_size = pcount();
streampos new_pos = EOF;
// Move the get pointer, if requested.
if (mode & ios::in) {
switch (dir) {
case ios::end:
off += cur_size;
break;
case ios::cur:
off += gptr() - pbase();
break;
default: /*case ios::beg: */
break;
}
if (off < 0 || (size_t)off > cur_size)
return EOF;
setg(base(), base() + off, base() + cur_size);
new_pos = off;
}
// Move the put pointer, if requested.
if (mode & ios::out) {
switch (dir) {
case ios::end:
off += cur_size;
break;
case ios::cur:
off += pptr() - pbase();
break;
default: /*case ios::beg: */
break;
}
if (off < 0 || (size_t)off > cur_size)
return EOF;
pbump(base() + off - pptr());
new_pos = off;
}
return new_pos;
}
int strstreambuf::pbackfail(int c)
{
if ((_flags & _S_NO_WRITES) && c != EOF)
return EOF;
return backupbuf::pbackfail(c);
}

View File

@ -1,105 +0,0 @@
// This is part of the iostream library, providing -*- C++ -*- input/output.
// Copyright (C) 1991 Per Bothner.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, 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
// Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public
// License along with this library; if not, write to the Free
// Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id: strstream.h,v 1.3 1993/08/02 17:22:42 mycroft Exp $
#ifndef __STRSTREAM_H
#define __STRSTREAM_H
#ifdef __GNUG__
#pragma interface
#endif
#include <iostream.h>
class strstreambuf : public backupbuf {
_G_size_t _len; // The current length is max(_len, _pptr-_pbase).
typedef void *(*_alloc_type)(_G_size_t);
typedef void (*_free_type)(void*);
_alloc_type _allocate_buffer;
_free_type _free_buffer;
void init_dynamic(_alloc_type alloc, _free_type free,
int initial_size = 128);
void init_static(char *ptr, int size, char *pstart);
void init_static(const char *ptr, int size);
protected:
int is_static() const { return _allocate_buffer == (_alloc_type)0; }
virtual int overflow(int = EOF);
virtual int underflow();
virtual int pbackfail(int c);
public:
virtual ~strstreambuf();
strstreambuf() { init_dynamic(0, 0); }
strstreambuf(int initial_size) { init_dynamic(0, 0, initial_size); }
strstreambuf(void *(*alloc)(_G_size_t), void (*free)(void*))
{ init_dynamic(alloc, free); }
strstreambuf(char *ptr, int size, char *pstart = NULL)
{ init_static(ptr, size, pstart); }
strstreambuf(unsigned char *ptr, int size, unsigned char *pstart = NULL)
{ init_static((char*)ptr, size, (char*)pstart); }
strstreambuf(const char *ptr, int size)
{ init_static(ptr, size); }
strstreambuf(const unsigned char *ptr, int size)
{ init_static((const char*)ptr, size); }
#ifndef _G_BROKEN_SIGNED_CHAR
strstreambuf(signed char *ptr, int size, signed char *pstart = NULL)
{ init_static((char*)ptr, size, (char*)pstart); }
strstreambuf(const signed char *ptr, int size)
{ init_static((const char*)ptr, size); }
#endif
// Note: frozen() is always true if is_static().
int frozen() { return _flags & _S_USER_BUF ? 1 : 0; }
void freeze(int n=1)
{ if (!is_static())
{ if (n) _flags |= _S_USER_BUF; else _flags &= ~_S_USER_BUF; } }
_G_size_t pcount();
char *str();
virtual streampos seekoff(streamoff, _seek_dir, int mode=ios::in|ios::out);
};
class strstreambase : virtual public ios {
public:
strstreambuf* rdbuf() { return (strstreambuf*)_strbuf; }
protected:
strstreambase() { }
strstreambase(char *cp, int n, int mode=ios::out);
};
class istrstream : public strstreambase, public istream {
public:
istrstream(const char*, int=0);
};
class ostrstream : public strstreambase, public ostream {
public:
ostrstream();
ostrstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
_G_size_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
char *str() { return ((strstreambuf*)_strbuf)->str(); }
void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
};
class strstream : public strstreambase, public iostream {
public:
strstream() : strstreambase() { init(new strstreambuf()); }
strstream(char *cp, int n, int mode=ios::out) :strstreambase(cp,n,mode){}
_G_size_t pcount() { return ((strstreambuf*)_strbuf)->pcount(); }
char *str() { return ((strstreambuf*)_strbuf)->str(); }
void freeze(int n = 1) { ((strstreambuf*)_strbuf)->freeze(n); }
int frozen() { return ((strstreambuf*)_strbuf)->frozen(); }
};
#endif /*!__STRSTREAM_H*/