[comp.text] GnuTeX version 1.3 source part 2

dfk@romeo.cs.duke.edu (David F. Kotz) (01/11/89)

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	gnutex
# This archive created: Tue Jan 10 11:16:46 1989
export PATH; PATH=/bin:$PATH
if test ! -d 'gnutex'
then
	mkdir 'gnutex'
fi
cd 'gnutex'
if test ! -d 'doc'
then
	mkdir 'doc'
fi
cd 'doc'
if test ! -d 'example'
then
	mkdir 'example'
fi
cd 'example'
if test -f '3.dat'
then
	echo shar: will not over-write existing file "'3.dat'"
else
sed 's/^X//' << \SHAR_EOF > '3.dat'
X-20.000000 -9.125028
X-19.000000 -9.109280
X-18.000000 -9.091787
X-17.000000 -9.072243
X-16.000000 -9.050265
X-15.000000 -9.025369
X-14.000000 -8.996933
X-13.000000 -8.964147
X-12.000000 -8.925931
X-11.000000 -8.880819
X-10.000000 -8.826766
X-9.000000 -8.760835
X-8.000000 -8.678648
X-7.000000 -8.573396
X-6.000000 -8.433886
X-5.000000 -8.240405
X-4.000000 -7.954906
X-3.000000 -7.494275
X-2.000000 -6.642892
X-1.000000 -4.712389
X0.000000 0.000000
X1.000000 4.712389
X2.000000 6.642892
X3.000000 7.494275
X4.000000 7.954906
X5.000000 8.240405
X6.000000 8.433886
X7.000000 8.573396
X8.000000 8.678648
X9.000000 8.760835
X10.000000 8.826766
X11.000000 8.880819
X12.000000 8.925931
X13.000000 8.964147
X14.000000 8.996933
X15.000000 9.025369
X16.000000 9.050265
X17.000000 9.072243
X18.000000 9.091787
X19.000000 9.109280
SHAR_EOF
fi # end of overwriting check
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThis directory has two simple examples of the use of gnutex. The first
Xuses LaTeX. The file second demonstrates some pure gnuplot aspects,
Xusing lasergnu instead of LaTeX.
X
XThe Makefile for the gnutex manual, in ../manual/Makefile, is a good
Xexample of a Makefile to maintain a document containing gnutex plots.
SHAR_EOF
fi # end of overwriting check
if test -f 'pic.tex'
then
	echo shar: will not over-write existing file "'pic.tex'"
else
sed 's/^X//' << \SHAR_EOF > 'pic.tex'
X\documentstyle{article}
X\textwidth=6in
X\begin{document}
X \begin{center}
X  \input{plot}
X \end{center}
X\end{document}
SHAR_EOF
fi # end of overwriting check
if test -f '1.dat'
then
	echo shar: will not over-write existing file "'1.dat'"
else
sed 's/^X//' << \SHAR_EOF > '1.dat'
X-20.000000 -3.041676
X-19.000000 -3.036427
X-18.000000 -3.030596
X-17.000000 -3.024081
X-16.000000 -3.016755
X-15.000000 -3.008456
X-14.000000 -2.998978
X-13.000000 -2.988049
X-12.000000 -2.975310
X-11.000000 -2.960273
X-10.000000 -2.942255
X-9.000000 -2.920278
X-8.000000 -2.892883
X-7.000000 -2.857799
X-6.000000 -2.811295
X-5.000000 -2.746802
X-4.000000 -2.651635
X-3.000000 -2.498092
X-2.000000 -2.214297
X-1.000000 -1.570796
X0.000000 0.000000
X1.000000 1.570796
X2.000000 2.214297
X3.000000 2.498092
X4.000000 2.651635
X5.000000 2.746802
X6.000000 2.811295
X7.000000 2.857799
X8.000000 2.892883
X9.000000 2.920278
X10.000000 2.942255
X11.000000 2.960273
X12.000000 2.975310
X13.000000 2.988049
X14.000000 2.998978
X15.000000 3.008456
X16.000000 3.016755
X17.000000 3.024081
X18.000000 3.030596
X19.000000 3.036427
SHAR_EOF
fi # end of overwriting check
if test -f '2.dat'
then
	echo shar: will not over-write existing file "'2.dat'"
else
sed 's/^X//' << \SHAR_EOF > '2.dat'
X-20.000000 -6.083352
X-19.000000 -6.072853
X-18.000000 -6.061191
X-17.000000 -6.048162
X-16.000000 -6.033510
X-15.000000 -6.016913
X-14.000000 -5.997955
X-13.000000 -5.976098
X-12.000000 -5.950620
X-11.000000 -5.920546
X-10.000000 -5.884511
X-9.000000 -5.840556
X-8.000000 -5.785765
X-7.000000 -5.715597
X-6.000000 -5.622591
X-5.000000 -5.493603
X-4.000000 -5.303271
X-3.000000 -4.996183
X-2.000000 -4.428595
X-1.000000 -3.141593
X0.000000 0.000000
X1.000000 3.141593
X2.000000 4.428595
X3.000000 4.996183
X4.000000 5.303271
X5.000000 5.493603
X6.000000 5.622591
X7.000000 5.715597
X8.000000 5.785765
X9.000000 5.840556
X10.000000 5.884511
X11.000000 5.920546
X12.000000 5.950620
X13.000000 5.976098
X14.000000 5.997955
X15.000000 6.016913
X16.000000 6.033510
X17.000000 6.048162
X18.000000 6.061191
X19.000000 6.072853
SHAR_EOF
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Demo directory for gnutex
X
Xdemo1:
X	gnutex < demo1.gnu
X	latex pic
X	@echo ----------------------
X	@echo Now print or view pic.dvi with some dvi output program
X
Xdemo2: 
X	lasergnu -l -f demo2.gnu
X
Xclean:
X	rm -f *.aux *.log *.dvi *~ plot.tex
SHAR_EOF
fi # end of overwriting check
if test -f 'demo1.gnu'
then
	echo shar: will not over-write existing file "'demo1.gnu'"
else
sed 's/^X//' << \SHAR_EOF > 'demo1.gnu'
Xset terminal latex
Xset output "plot.tex"
Xset size 3.5,3
Xset title "This is a very long title\\because it has\\three lines"
Xset xlabel "This is the $x$ axis\\with more than two\\lines in the label"
Xset ylabel "This is a longer\\version of\\the $y$ axis"
Xset style new1 "$\otimes$" 3 "\circle*{100}" "\circle*{200}" "\circle*{300}"
Xplot "3.dat" with new1
SHAR_EOF
fi # end of overwriting check
if test -f 'demo2.gnu'
then
	echo shar: will not over-write existing file "'demo2.gnu'"
else
sed 's/^X//' << \SHAR_EOF > 'demo2.gnu'
Xset samples 50
Xplot [-10:10] sin(x),atan(x),cos(atan(x))
Xset samples 100 
Xplot [-pi/2:pi] cos(x),-(sin(x) > sin(x+1) ? sin(x) : sin(x+1))
Xset samples 200 
Xplot [-3:5] asin(x),acos(x)
Xplot [-30:20] besj0(x)*0.12e1 with impulses, (x**besj0(x))-2.5 with points
Xset samples 400
Xplot [-10:10] real(sin(x)**besj0(x))
Xplot [-5*pi:5*pi] [-5:5] real(tan(x)/atan(x)), 1/x
Xset autoscale
Xset samples 800
Xplot [-30:20] sin(x*20)*atan(x)
Xplot [-19:19] '1.dat' with impulses ,'2.dat' ,'3.dat' with lines
SHAR_EOF
fi # end of overwriting check
cd ..
cd ..
if test ! -d 'help'
then
	mkdir 'help'
fi
cd 'help'
if test ! -d 'plot'
then
	mkdir 'plot'
fi
cd 'plot'
if test -f 'ranges'
then
	echo shar: will not over-write existing file "'ranges'"
else
sed 's/^X//' << \SHAR_EOF > 'ranges'
XThese two options specify the region of the plot which will be displayed.
X
XRanges may be provided on the 'plot' command line as synonyms for the
X'set xrange' and 'set yrange' commands.
X
XSyntax:  [{dummy-var =} {xmin : xmax}] { [{ymin : ymax}] }
X
XWhere dummy-var is the independent variable ('x' is used by default) and
Xthe min and max terms can be expressions or constants.
X
XBoth the min and max terms are optional.  The ':' is also optional if
Xneither a min nor a max term is specified.  This allows '[]' to be used
Xas a null range specification.
X
XSpecifying a Y range turns autoscaling OFF.
X
XExamples:
X
Xplot cos(x)                             ; use current ranges
Xplot [-10:30] sin(pi*x)/(pi*x)          ; set xrange only
Xplot [t = -10 :30]  sin(pi*t)/(pi*t)    ; same, but use t as dummy-var
Xplot [-pi:pi] [-3:3]  tan(x), 1/x       ; set y and xranges
Xplot [] [-2:sin(5)*-8] sin(x)**besj0(x) ; set only yrange
Xplot [:200] [-pi:]  exp(sin(x))         ; set xmax and ymin only
SHAR_EOF
fi # end of overwriting check
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XThe 'plot' command is the primary command of the program.  It displays
Xfunctions and data in many, many ways.  The full syntax of this
Xcommand is:
X
X  plot {ranges}   <function> {style} {, <function> {style}...}
X
XWhere <function> is either a mathematical expression or the name of a
Xdata file enclosed in quotes.  User-defined functions and variables may also 
Xbe defined here.
X
XCurly braces {,} denote optional items.
X
XA 'plot' command can be as simple as
X
X   plot sin(x)
X
Xor as complex as (!)
X
X   plot [t=1:100] [-pi:pi*2] tan(t), "data.1" with lines, besj0(t) with points
SHAR_EOF
fi # end of overwriting check
if test -f 'style'
then
	echo shar: will not over-write existing file "'style'"
else
sed 's/^X//' << \SHAR_EOF > 'style'
XPlots may be displayed in one of these styles: 'lines', 'points',
X'linespoints', 'impulses', or 'dots'.  The 'lines' style connects
Xadjacent points with lines.  The 'points' style displays a small
Xsymbol at each point.  The 'linespoints' style is a combination of the
Xprevious two styles.  The 'impulses' style displays a vertical line
Xfrom the X axis to each point. The 'dots' style is like the 'points'
Xstyle except a very tiny dot is plotted at each point, and the symbol
Xdoes not vary from plot to plot. This is useful for plotting very many
Xpoints to get a feel for the distribution. In addition, for LaTeX
Xoutput only, there are user-defined styles (see the 'set style'
Xcommand in 'user-styles').
X
XDefault styles are chosen with the 'set function style' and 'set data style'
Xcommands.
X
XSyntax:  with <style>
X
XWhere <style> is one of 'lines', 'points', 'linespoints', 'impulses',
X'dots', or a user-defined style. These keywords may NOT be
Xabbreviated.
X
XExamples:                              Displays:
Xplot sin(x) with impulses              ; sin(x) with impulses
Xplot [-9:30]  sin(x) w points, cos(x)  ; sin(x) with points, cos(x) default
Xplot [] [-2:5] tan(x), "data.1" with l ; tan(x) default, "data.1" with lines
Xplot "leastsq.dat" w i                 ; "leastsq.dat" with impulses
SHAR_EOF
fi # end of overwriting check
if test -f 'data_file'
then
	echo shar: will not over-write existing file "'data_file'"
else
sed 's/^X//' << \SHAR_EOF > 'data_file'
XDiscrete data contained in a file can displayed by specifying the
Xname of the data file (enclosed in quotes) on the 'plot' command line.
X
XData files should contain one data point per line.  A data point may be
Xspecified either as an X and Y value separated by blank space, or as
Xjust the Y value, in which case the program will use the number of the 
Xcoordinate as the X value.  Coordinate numbers starts at 0 and are
Xincremented for each data point read.  Blank lines and lines beginning
Xwith ! or # will be treated as comments and ignored.
X
X
XThis example compares the data in the file population.dat to a theoretical
Xcurve:
X          pop(x) = 103*exp((1965-x)/10)
X          plot [1960:1990] 'population.dat', pop(x)
X
XThe file population.dat might contain:
X
X! Gnu population in Antarctica since 1965
X1965   103
X1970   55
X1975   34
X1980   24
X1985   10
SHAR_EOF
fi # end of overwriting check
cd ..
if test ! -d 'expressions'
then
	mkdir 'expressions'
fi
cd 'expressions'
if test ! -d 'functions'
then
	mkdir 'functions'
fi
cd 'functions'
if test -f 'sinh'
then
	echo shar: will not over-write existing file "'sinh'"
else
sed 's/^X//' << \SHAR_EOF > 'sinh'
XThis function returns the hyperbolic sine of its argument.  'sinh' expects
Xits argument to be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'tan'
then
	echo shar: will not over-write existing file "'tan'"
else
sed 's/^X//' << \SHAR_EOF > 'tan'
XThis function returns the tangent of its argument.  'tan' expects its argument
Xto be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'int'
then
	echo shar: will not over-write existing file "'int'"
else
sed 's/^X//' << \SHAR_EOF > 'int'
XThis function returns the integer part of its argument, truncated toward
Xzero.
SHAR_EOF
fi # end of overwriting check
if test -f 'besj0'
then
	echo shar: will not over-write existing file "'besj0'"
else
sed 's/^X//' << \SHAR_EOF > 'besj0'
XThis function returns the j0th Bessel function of its argument.  'besj0'
Xexpects its argument to be in radians.
SHAR_EOF
fi # end of overwriting check
if test -f 'tanh'
then
	echo shar: will not over-write existing file "'tanh'"
else
sed 's/^X//' << \SHAR_EOF > 'tanh'
XThis function returns the hyperbolic tangent of its argument.  'tanh' expects
Xits argument to be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'floor'
then
	echo shar: will not over-write existing file "'floor'"
else
sed 's/^X//' << \SHAR_EOF > 'floor'
XThis function returns the smallest integer not greater than its argument.
XFor complex numbers, 'floor' returns the smallest integer not greater than
Xthe real part of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'abs'
then
	echo shar: will not over-write existing file "'abs'"
else
sed 's/^X//' << \SHAR_EOF > 'abs'
XThis function returns the absolute value of its argument.
XThe returned value is of the same type as the argument.
X
XFor complex arguments, abs(x) is defined as the length of x in the
Xcomplex plane [i.e.  sqrt(real(arg)**2 + imag(arg)**2) ].
SHAR_EOF
fi # end of overwriting check
if test -f 'besj1'
then
	echo shar: will not over-write existing file "'besj1'"
else
sed 's/^X//' << \SHAR_EOF > 'besj1'
XThis function returns the j1st Bessel function of its argument.  'besj1'
Xexpects its argument to be in radians.
SHAR_EOF
fi # end of overwriting check
if test -f 'arg'
then
	echo shar: will not over-write existing file "'arg'"
else
sed 's/^X//' << \SHAR_EOF > 'arg'
XThis function returns the phase of a complex number, in radians.  
SHAR_EOF
fi # end of overwriting check
if test -f 'besy0'
then
	echo shar: will not over-write existing file "'besy0'"
else
sed 's/^X//' << \SHAR_EOF > 'besy0'
XThis function returns the y0th Bessel function of its argument.  'besy0'
Xexpects its argument to be in radians.
SHAR_EOF
fi # end of overwriting check
if test -f 'cos'
then
	echo shar: will not over-write existing file "'cos'"
else
sed 's/^X//' << \SHAR_EOF > 'cos'
XThis function returns the cosine of its argument.  'cos' expects its argument
Xto be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'sqrt'
then
	echo shar: will not over-write existing file "'sqrt'"
else
sed 's/^X//' << \SHAR_EOF > 'sqrt'
XThis function returns the square root of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'exp'
then
	echo shar: will not over-write existing file "'exp'"
else
sed 's/^X//' << \SHAR_EOF > 'exp'
XThis function returns the exponential function of its argument (e raised to
Xthe power of its argument).
SHAR_EOF
fi # end of overwriting check
if test -f 'log'
then
	echo shar: will not over-write existing file "'log'"
else
sed 's/^X//' << \SHAR_EOF > 'log'
XThis function returns the natural logarithm (base e) of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'atan'
then
	echo shar: will not over-write existing file "'atan'"
else
sed 's/^X//' << \SHAR_EOF > 'atan'
XThis function returns the arc tangent (inverse tangent) of its argument.
X'atan' returns its argument in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'sgn'
then
	echo shar: will not over-write existing file "'sgn'"
else
sed 's/^X//' << \SHAR_EOF > 'sgn'
XThis function returns 1 if its argument is positive, -1 if its  
Xargument is negative, and 0 if its argument is 0.  If the argument 
Xis a complex value, the imaginary component is ignored.
SHAR_EOF
fi # end of overwriting check
if test -f 'sin'
then
	echo shar: will not over-write existing file "'sin'"
else
sed 's/^X//' << \SHAR_EOF > 'sin'
XThis function returns the sine of its argument.  'sin' expects its argument
Xto be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'log10'
then
	echo shar: will not over-write existing file "'log10'"
else
sed 's/^X//' << \SHAR_EOF > 'log10'
XThis function returns the logarithm (base 10) of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'real'
then
	echo shar: will not over-write existing file "'real'"
else
sed 's/^X//' << \SHAR_EOF > 'real'
XThis function returns the real part of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'besy1'
then
	echo shar: will not over-write existing file "'besy1'"
else
sed 's/^X//' << \SHAR_EOF > 'besy1'
XThis function returns the y1st Bessel function of its argument.  'besy1'
Xexpects its argument to be in radians.
SHAR_EOF
fi # end of overwriting check
if test -f 'ceil'
then
	echo shar: will not over-write existing file "'ceil'"
else
sed 's/^X//' << \SHAR_EOF > 'ceil'
XThis function returns the largest integer not less than its argument.
XFor complex numbers, 'ceil' returns the largest integer not less than
Xthe real part of its argument.
SHAR_EOF
fi # end of overwriting check
if test -f 'cosh'
then
	echo shar: will not over-write existing file "'cosh'"
else
sed 's/^X//' << \SHAR_EOF > 'cosh'
XThis function returns the hyperbolic cosine of its argument.  'cosh' expects
Xits argument to be in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'imag'
then
	echo shar: will not over-write existing file "'imag'"
else
sed 's/^X//' << \SHAR_EOF > 'imag'
XThis function returns the imaginary part of its argument as a real number.
SHAR_EOF
fi # end of overwriting check
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XThe functions in GNUTEX are the same as the corresponding functions in
Xthe UNIX math library, except that all functions accept integer, real,
Xand complex arguments, unless otherwise noted.  The BASIC sgn()
Xfunction is also supported.
SHAR_EOF
fi # end of overwriting check
if test -f 'acos'
then
	echo shar: will not over-write existing file "'acos'"
else
sed 's/^X//' << \SHAR_EOF > 'acos'
XThis function returns the arc cosine (inverse cosine) of its argument.  'acos'
Xreturns its argument in radians. 
SHAR_EOF
fi # end of overwriting check
if test -f 'asin'
then
	echo shar: will not over-write existing file "'asin'"
else
sed 's/^X//' << \SHAR_EOF > 'asin'
XThis function returns the arc sin (inverse sin) of its argument.  'asin'
Xreturns its argument in radians. 
SHAR_EOF
fi # end of overwriting check
cd ..
if test ! -d 'operators'
then
	mkdir 'operators'
fi
cd 'operators'
if test -f 'binary'
then
	echo shar: will not over-write existing file "'binary'"
else
sed 's/^X//' << \SHAR_EOF > 'binary'
XThe following is a list of all the binary operators and their usage:
X
XSymbol      Example     Explanation
X**          a**b        exponentiation
X*           a*b         multiplication
X/           a/b         division
X%           a%b         modulo
X+           a+b         addition
X-           a-b         subtraction
X==          a==b        equality
X!=          a!=b        inequality
X&           a&b         bitwise and
X^           a^b         bitwise exclusive or
X|           a|b         bitwise inclusive or
X&&          a&&b        logical and
X||          a||b        logical or
X?:          a?b:c       terniary operation
X
XThe terniary operator evaluates its first argument (a).  If it is true
X(non-zero) the second argument (b) is returned, otherwise the
Xthird argument (c) is returned. 
SHAR_EOF
fi # end of overwriting check
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XThe operators in GNUTEX are the same as the corresponding operators
Xin the C programming language, except that all operators accept integer, real,
Xand complex arguments, unless otherwise noted.  The FORTRAN **
X(exponentiation) operator is also supported.
X
XParentheses may be used to change order of evaluation.
SHAR_EOF
fi # end of overwriting check
if test -f 'unary'
then
	echo shar: will not over-write existing file "'unary'"
else
sed 's/^X//' << \SHAR_EOF > 'unary'
XThe following is a list of all the unary operators and their usage:
X
XSymbol      Example     Explantion
X-           -a          unary minus
X~           ~a          one's complement
X!           !a          logical negation
SHAR_EOF
fi # end of overwriting check
cd ..
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XIn general, any mathematical expression accepted by C, FORTRAN, Pascal, or
XBASIC is valid.  The precedence of these operators is determined by the
Xspecifications of the C programming language.  White space (spaces and tabs)
Xis ignored inside expressions.
X
XComplex constants may be expressed as {real,imag}, where <real> and
X<imag> must be numerical constants.  For example {3,2} represents 
X3 + 2i; {0,1} represents 'i' itself.
SHAR_EOF
fi # end of overwriting check
cd ..
if test ! -d 'set-show'
then
	mkdir 'set-show'
fi
cd 'set-show'
if test -f 'output'
then
	echo shar: will not over-write existing file "'output'"
else
sed 's/^X//' << \SHAR_EOF > 'output'
XBy default, plots are displayed to the standard output.  The 'set output'
Xcommand redirects the displays to the specified file or device.
X
XSyntax:  set output {filename}
X         show output
X
XThe filename must be enclosed in quotes.  If the filename is omitted, output
Xwill be sent to the standard output.
SHAR_EOF
fi # end of overwriting check
if test -f 'samples'
then
	echo shar: will not over-write existing file "'samples'"
else
sed 's/^X//' << \SHAR_EOF > 'samples'
XThe sampling rates of functions may be changed by the 'set samples'
Xcommand.  By default, sampling is set to 160 points.  A higher sampling
Xrate will produce more accurate plots, but will take longer.  In generating
Xplots, GNUTEX will use either the sampling rate set or the resolution of
Xthe current output device, whichever is smaller.
X
XSyntax:  set samples <expression>
X         show samples
SHAR_EOF
fi # end of overwriting check
if test -f 'style'
then
	echo shar: will not over-write existing file "'style'"
else
sed 's/^X//' << \SHAR_EOF > 'style'
XPlots may be displayed in one of these styles: 'lines', 'points',
X'linespoints', 'impulses', or 'dots'.  The 'lines' style connects
Xadjacent points with lines.  The 'points' style displays a small
Xsymbol at each point.  The 'linespoints' style is a combination of the
Xprevious two styles.  The 'impulses' style displays a vertical line
Xfrom the X axis to each point. The 'dots' style is like the 'points'
Xstyle except a very tiny dot is plotted at each point, and the symbol
Xdoes not vary from plot to plot. This is useful for plotting very many
Xpoints to get a feel for the distribution. In addition, for LaTeX
Xoutput only, there are user-defined styles (see the 'set style'
Xcommand in 'user-styles').
X
XDefault styles are chosen with the 'set function style' and 'set data
Xstyle' commands.
X
XSyntax:  set function style <style>
X         set data style <style>
X         show function style
X         show data style
X
XWhere <style> is one of 'lines', 'points', 'linespoints', 'impulses',
X'dots', or a user-defined style. These keywords may NOT be
Xabbreviated.
X
SHAR_EOF
fi # end of overwriting check
if test -f 'user-styles'
then
	echo shar: will not over-write existing file "'user-styles'"
else
sed 's/^X//' << \SHAR_EOF > 'user-styles'
XLATEX ONLY
X
X  If you find the "dot" approximation to lines to be inadequate, or
Xdesire your different curves on the same plot to have different
Xstyles, then you can define your own style (up to 16 may be defined).
XA style may be defined at any time with a command of the form
X	   set style <name> <point>
Xor
X	   set style <name> <spacing> <dot>...
Xor
X	   set style <name> <point> <spacing> <dot>...  
X
XThe first form defines a style similar to "points", the second similar
Xto "lines" and the third to "linespoints". The <name> is any
Xidentifier, just as with user-defined variables and functions (it may
Xnot be lines, points, impulses, linespoints, or dots). To use the style,
Xsimply use the <name> where you would use any of the standard
Xlinestyle names: "with <name>", "set data style <name>", or "set
Xfunction style <name>".
X
XThe <point> is a quoted string of LaTeX source which describes text to
Xbe plotted at each point. Picture-mode and math-mode commands are the
Xmost useful.  For example, "\circle*{100}" draws a disk 1pt in
Xdiameter at each data point (the units of picture coordinates in use
Xare 1/100 point). "$\Diamond$" produces a large diamond symbol.
X
XThe <spacing> and <dot> arguments define a line in terms of a sequence
Xof "dots" to be output every <spacing> points along the line to be
Xplotted. <spacing> is a real number whose units are points. Each dot
X(up to 5 dots are allowed) is a quoted string of LaTeX text, as with
Xthe point above. The dots are plotted in rotation along the whole
Xcurve. 
X
XThus, to simulate a linespoints linestyle with alternating big and
Xlittle dots every 4 points along the curve but to use a plus sign at
Xeach data point,
X	   set style mine "$+$" 4 "\circle*{100}" "\circle*{200}"
X
XThe default style is as if 
X	   set style lines 2 "\circle*{1}"
X    	   set style linespoints <varies> 2 "\circle*{1}"
XHad been executed. (The smallest circle that will be drawn is about
X100 units; smaller sizes as this one will use that smallest size).
XLinespoints is special in that its points vary with each curve on the
Xplot, as with classic gnuplot. This is not possible to embody in a
Xsingle user-defined linestyle.
X
SHAR_EOF
fi # end of overwriting check
if test -f 'terminal'
then
	echo shar: will not over-write existing file "'terminal'"
else
sed 's/^X//' << \SHAR_EOF > 'terminal'
XGNUTEX supports many different graphics devices.  Use the 'set terminal'
Xcommand to select the type of device for which GNUTEX will produce output.
X
XSyntax:  set terminal {terminal-type}
X         show terminal
X
XIf <terminal-type> is omitted, the program will list the available terminal
Xtypes.  <terminal-type> may be abbreviated.
X
XUse 'set output' to redirect this output to a file or device.
SHAR_EOF
fi # end of overwriting check
if test -f 'ylabel'
then
	echo shar: will not over-write existing file "'ylabel'"
else
sed 's/^X//' << \SHAR_EOF > 'ylabel'
XLaTeX ONLY:
X
XThe plot is labeled in a variety of ways.  The ticks on the x and y
Xaxes are labeled with the appropriate numbers. The axes may be labeled
Xand a title provided for the plot with new 'set' commands.  The labels
Xin effect at the time of the "plot" command are used, so they should
Xbe set before the plot. Once set, they retain their values until
Xexplicitly changed. 
X
XTo label the y-axis, for example,
X
X    set ylabel "This is the y axis"
X
XThis may be more complex:
X    set ylabel "This is a longer\\version of\\the $y$ axis"
XHere there are line breaks, and math mode is used to make the 'y' look
Xlike a variable.
X
XIf the ylabel is not coming out quite right (too close to the plot),
Xits position may be adjusted with a second parameter, such as
X    set ylabel "This is the y axis" 2
XThis will slide the y label about 2 characters further left (away from
Xthe plot). Positive and negative integers are allowed.
SHAR_EOF
fi # end of overwriting check
if test -f 'zero'
then
	echo shar: will not over-write existing file "'zero'"
else
sed 's/^X//' << \SHAR_EOF > 'zero'
XGNUTEX will not display points when their imaginary parts are greater
Xthan the 'zero' threshold.  The default 'zero' value is 1e-8.
X
XSyntax:  set zero <expression>
X         show zero
SHAR_EOF
fi # end of overwriting check
if test -f 'xrange'
then
	echo shar: will not over-write existing file "'xrange'"
else
sed 's/^X//' << \SHAR_EOF > 'xrange'
XThe 'set xrange' command sets the horizontal range of values which will
Xbe displayed.
X
XThis range may also be specified on the 'plot' command line.
X
XSyntax:  set xrange [{xmin : xmax}]
X
XWhere <xmin> and <xmax> terms are expressions or constants.
X
XBoth the <xmin> and <xmax> terms are optional.
SHAR_EOF
fi # end of overwriting check
if test -f 'clip'
then
	echo shar: will not over-write existing file "'clip'"
else
sed 's/^X//' << \SHAR_EOF > 'clip'
XGnutex normally clips (actually, does not plot at all) data points
Xthat fall within but too close to the boundaries (this is so the large
Xsymbols used for points will not extend outside the boundary lines).
XWith the user-defined styles of Latex it is often desirable to make
Xsmaller points, and thus points near the boundaries may be plotted. To
Xturn off clipping, use
X    set noclip
XTo turn it back on, use
X    set clip
XThe default is 'clip'. Without clipping you may have points near the
Xboundaries that look bad; try adjusting the x and y ranges. Indeed,
Xfor some terminal types this may cause errors.
X
SHAR_EOF
fi # end of overwriting check
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XThe 'set' command sets LOTS of options.
X
XThe 'show' command shows their settings.  'show all' shows all the settings.
SHAR_EOF
chmod +x '.general'
fi # end of overwriting check
if test -f 'size'
then
	echo shar: will not over-write existing file "'size'"
else
sed 's/^X//' << \SHAR_EOF > 'size'
XLATEX ONLY:
X
XThe 'set size' command will set the size of the plot, in inches.
X
XFor example,
X
X    set size 5, 4
X
Xtells gnutex to use a 5 inch wide by 4 inch high box for the plot.
XThis is the size of the actual plotting area; labels (see the 'set
Xxlabel', 'set ylabel', and 'set title' commands) will extend outside
Xof this size.
SHAR_EOF
fi # end of overwriting check
if test -f 'title'
then
	echo shar: will not over-write existing file "'title'"
else
sed 's/^X//' << \SHAR_EOF > 'title'
XThe plot is labeled in a variety of ways.  A title may be provided for
Xthe plot with 'set title' commands.  The title in effect at the time
Xof the "plot" command is used, so it should be set before the plot.
XOnce set, it retains its values until explicitly changed.
X
XFor example,
X
X    set title "This is the title"
X
XWhen not in latex, the title shows up in the upper-left-hand corner of
Xthe plot, whenever the plot is being labeled.
X
XWith Latex, this may be more complex:
X    set title "This is a very long title\\because it has\\three lines"
SHAR_EOF
fi # end of overwriting check
if test -f 'ytics'
then
	echo shar: will not over-write existing file "'ytics'"
else
sed 's/^X//' << \SHAR_EOF > 'ytics'
XLaTeX ONLY:
X
XSometimes the x- or y-axis numbers really don't mean anything, and you
Xwould rather not have the numbers and tics printed on the axis. If
Xthis is the case, insert a
X    set noxtics
Xand/or
X    set noytics
Xbefore the plot command. To turn them back on use
X    set xtics
X    set ytics
SHAR_EOF
fi # end of overwriting check
if test -f 'yrange'
then
	echo shar: will not over-write existing file "'yrange'"
else
sed 's/^X//' << \SHAR_EOF > 'yrange'
XThe 'set yrange' command sets the vertical range of values which will
Xbe displayed.  This command turns autoscaling OFF.
X
XThis range may also be specified on the 'plot' command line.
X
XSyntax:  set yrange [{ymin : ymax}]
X
XWhere <ymin> and <ymax> terms are expressions or constants.
X
XBoth the <ymin> and <ymax> terms are optional.
SHAR_EOF
fi # end of overwriting check
if test -f 'autoscale'
then
	echo shar: will not over-write existing file "'autoscale'"
else
sed 's/^X//' << \SHAR_EOF > 'autoscale'
XAutoscaling is the default for both the x and y axes.  If y
Xautoscaling is on, the y axis is automatically scaled to fit the range
Xof the function or data being plotted.  If x autoscaling is on, the x
Xrange is scaled to the data file(s) being plotted; any functions
Xplotted on the same curve will use the same range. If only functions
Xare plotted, the current x range is used.
X
XIf autoscaling is not on for an axis, the current range for that axis
Xis used. The current range is the range used for the last plot
Xcommand, or defined by the 'set xrange' and 'set yrange' commands, or
X[-10:10] initially.
XThe syntax is
X   set autoscale [{axes}]
X   set noautoscale [{axes}]
X   show autoscale
X
XThe optional {axes} parameter specifies the axes affected by the
Xcommand. If {axes} is 'x' or 'y', the command affects the x or y axis,
Xrespectively. If {axes} is 'xy', 'yx', or absent, the command affects
Xboth axes.
SHAR_EOF
fi # end of overwriting check
if test -f 'xlabel'
then
	echo shar: will not over-write existing file "'xlabel'"
else
sed 's/^X//' << \SHAR_EOF > 'xlabel'
XLaTeX ONLY:
X
XThe plot is labeled in a variety of ways.  The ticks on the x and y
Xaxes are labeled with the appropriate numbers. The axes may be labeled
Xand a title provided for the plot with 'set' commands.  The labels
Xin effect at the time of the "plot" command are used, so they should
Xbe set before the plot. Once set, they retain their values until
Xexplicitly changed. 
X
XTo label the x-axis, for example,
X
X    set xlabel "This is the x axis"
X
XThis may be more complex:
X    set xlabel "This is the $x$ axis\\with more than two\\lines in the label"
XHere there are line breaks, and math mode is used to make the 'x' look
Xlike a variable.
SHAR_EOF
fi # end of overwriting check
if test -f 'functions'
then
	echo shar: will not over-write existing file "'functions'"
else
sed 's/^X//' << \SHAR_EOF > 'functions'
XThe 'show functions' command lists all user-defined functions and their
Xdefinitions.
X
XSyntax:  show functions
SHAR_EOF
fi # end of overwriting check
if test -f 'logscale'
then
	echo shar: will not over-write existing file "'logscale'"
else
sed 's/^X//' << \SHAR_EOF > 'logscale'
XLog scaling may be set on the X and/or Y axis.
X
XSyntax:  set logscale <axes>
X         set nologscale
X         show logscale
X
XWhere <axes> is either 'x', 'y', or 'xy'.
SHAR_EOF
fi # end of overwriting check
if test -f 'variables'
then
	echo shar: will not over-write existing file "'variables'"
else
sed 's/^X//' << \SHAR_EOF > 'variables'
XThe 'show variables' command lists all user-defined variables and their
Xvalues.
X
XSyntax:  show variables
SHAR_EOF
fi # end of overwriting check
if test -f 'xtics'
then
	echo shar: will not over-write existing file "'xtics'"
else
sed 's/^X//' << \SHAR_EOF > 'xtics'
XLaTeX ONLY:
X
XSometimes the x- or y-axis numbers really don't mean anything, and you
Xwould rather not have the numbers and tics printed on the axis. If
Xthis is the case, insert a
X    set noxtics
Xand/or
X    set noytics
Xbefore the plot command. To turn them back on use
X    set xtics
X    set ytics
SHAR_EOF
fi # end of overwriting check
if test -f 'format'
then
	echo shar: will not over-write existing file "'format'"
else
sed 's/^X//' << \SHAR_EOF > 'format'
XLATEX ONLY
X
XThe format of the tic-mark labels may be set with the "set format"
Xcommand. The default format used for both axes is "$%g$", but other
Xformats such as "%.2f" or "$%3.0f \mu$sec" are often desirable.
XAnything accepted by printf when given a DOUBLE-PRECISION number, and
Xthen accepted by LaTeX in LR mode, will work. In particular, the
Xformats f, e, and g will work, and the d, o, x, c, s, and u formats
Xwill not work. 
X
XSyntax:  set format <axes> "format-string"
X         show format
X
XWhere <axes> is either 'x', 'y', 'xy', or nothing (which is the same
Xas 'xy'). The length of the string representing a ticmark (after
Xformatting with printf) is restricted to 100 characters.
SHAR_EOF
fi # end of overwriting check
cd ..
if test -f 'print'
then
	echo shar: will not over-write existing file "'print'"
else
sed 's/^X//' << \SHAR_EOF > 'print'
XThis command prints the value of <expression>. 
X
XSyntax:  print <expression>
X
XSee 'expressions'.
SHAR_EOF
fi # end of overwriting check
if test -f '.general'
then
	echo shar: will not over-write existing file "'.general'"
else
sed 's/^X//' << \SHAR_EOF > '.general'
XGNUTEX is a command-driven interactive function plotting program.
XIt is case sensitive (commands and function names written in lowercase
Xare not the same as those written in CAPS).  All command names may be
Xabbreviated, as long as the abbreviation is not ambiguous.
X
XCommand may extend over several input lines, by ending each line but
Xthe last with a backslash (\). The backslash must be the LAST
Xcharacter on each line. The effect is as if the backslash and newline
Xwere not there. That is, no white space is implied, nor is a comment
Xterminated. Therefore, commenting out a continued line comments out
Xthe entire command.
SHAR_EOF
fi # end of overwriting check
if test -f 'clear'
then
	echo shar: will not over-write existing file "'clear'"
else
sed 's/^X//' << \SHAR_EOF > 'clear'
XThis command erases the current screen or output device as specified by
X'set output'.  This usually generates a formfeed on hardcopy devices.
XUse 'set terminal' to set the device type.
SHAR_EOF
fi # end of overwriting check
if test -f 'comments'
then
	echo shar: will not over-write existing file "'comments'"
else
sed 's/^X//' << \SHAR_EOF > 'comments'
X
XComments:
X  Comments are now supported: a # may appear in most places in a line
Xand gnutex will ignore the rest of the line. It will not have this
Xaffect inside quotes, inside numbers (incl. complex numbers), inside
Xcommand substitutions, etc. In short, it works anywhere it makes sense
Xto work.
SHAR_EOF
fi # end of overwriting check
if test -f 'key'
then
	echo shar: will not over-write existing file "'key'"
else
sed 's/^X//' << \SHAR_EOF > 'key'
XLaTeX ONLY:
X
XPlotting a Key:
X  If you wish a key describing the plots to be made, use the "key" command: 
X	key x,y "description1" w <style1> [, "description2" w <style2>"] ...
X
XThe key command looks a lot like a plot command. The coordinates x,y
Xspecify the location of the key on the plot (see below).  The key is
Xdrawn as a sequence lines, with one plot described on each line. On
Xthe left-hand side of each line is a representation that attempts to
Xmimic the way the curve is plotted (eg, a bunch of dots for a line,
Xthe point symbol for a point, etc). On the right side of each line is
Xthe text "description" given in the command. The lines are vertically
Xarranged so an imaginary straight line divides the left- and
Xright-hand sides of the key. It is the x-coordinate of this line that
Xyou specify with the x in the key command; the y in the key command is
Xthe bottom of the key.
X
XFor example, the plot command
X	plot "foo" w points, "bar" w lines, "funky" w linespoints
Xfollowed by
X	key 5,5 "This is foo" w points, "This is bar" w lines, \
X		"This is funky" w linespoints
Xwould give us a key that looks (roughly) like this:
X	    <> This is foo
X	.....  This is bar
X	...+.. This is funky
X(The <> is a diamond).
X
XAny styles may be used in the key entries, including user-defined
Xstyles. For the points and linespoints styles, the point type plotted
Xis determined in the same way as in the plot command, so your key
Xentries should be in the same order as in the plot command. Note that
Xa key entry with an empty (ie "") description will not be included in
Xthe key, but may be included to affect the point-type determination.
XFor example, if you didn't want to key the "foo" curve above, but you
Xwanted "funky" to look right, the key command is
X	key 5,5 "" w points, "This is bar" w lines, \
X		"This is funky" w linespoints
Xand gives us a key that looks (roughly) like this:
X	.....  This is bar
X	...+.. This is funky
X
XThe key is fairly rough at this time and I may find ways to make it
Xlook better. Suggestions welcome.
SHAR_EOF
fi # end of overwriting check
if test -f 'label'
then
	echo shar: will not over-write existing file "'label'"
else
sed 's/^X//' << \SHAR_EOF > 'label'
XLATEX ONLY:
X
XArbitrary labels may be placed on the most recent plot, using the new
X"label" command. The syntax is
X    label x,y "text"
Xwhere x,y is some coordinate in your plot's coordinate system (the
Xcommas are important). The text is any arbitrary LaTeX input, and will
Xbe processed in LR mode.  The text is centered at the point x,y. The
Xlabel command should follow the plot command. Any number of labels may
Xbe placed.
X
XIf you want to adjust the way the label is positioned with respect to
Xthe point x,y, add another parameter:
X    label x,y "text" pos
Xwhere pos is one of r,l,t,b,lt,lb,rt,rb indicating that the text
Xshould be placed so that the point is at the right center, left
Xcenter, top center, bottom center, left top corner, etc. 
X
XAn arrow can be drawn out from the point simply by giving its
Xlength in problem coordinates, after the pos:
X    label x,y "text" pos length
XThe length is defined to be the HORIZONTAL extent of the arrow, unless
Xthe arrow is vertical, in which case it is the vertical extent of the
Xarrow.  The arrow is drawn AWAY FROM the text; for example, if pos is
Xlt, then away is defined to be up and to the left. If it is b, away is
Xdefined to be down. This allows for eight different directions of
Xarrows.
X
XFurther control over the slope of the arrow can be gained by
Xspecifying exactly the slope you want. You should read about vectors
Xon page 198 in the LaTeX manual. The command looks like
X    label x,y "text" pos length, h_slope, v_slope
X(the commas are important). The h_slope and v_slope are integers in
Xthe range -4 to 4, which specify the slope of the line (run, rise).
XA horizontal line is 1,0, vertical is 0,1. The two numbers may not
Xhave a common divisor other than +1 or -1.
X
XLabels outside of the plotted boundaries are permitted but may
Xinterfere with axes labels or other text; use at your own risk.
SHAR_EOF
fi # end of overwriting check
if test -f 'save'
then
	echo shar: will not over-write existing file "'save'"
else
sed 's/^X//' << \SHAR_EOF > 'save'
XThis command saves either user-defined functions, variables, or both
Xto the specified file.
X
XSyntax:    save  {option} <filename>
X
XWhere <option> is either 'functions' or 'variables'.  If no option
Xis used GNUTEX saves both functions and variables.
X
X'save'd files are written in text format and may be read by the 
X'load' command.
X
XThe filename must be enclose in quotes.
SHAR_EOF
fi # end of overwriting check
if test -f 'shell'
then
	echo shar: will not over-write existing file "'shell'"
else
sed 's/^X//' << \SHAR_EOF > 'shell'
XThe 'shell' command spawns an interactive shell.  To return to GNUTEX,
Xtype 'logout' if using VMS, 'exit' or your END-OF-FILE character if
Xusing Unix, or 'exit' if using MS-DOS.
X
XA single shell command may be spawned by preceding it with the ! character
Xat the beginning of a command line.  Control will return immediately to
XGNUTEX after this command is executed.  For example,
X
X    ! dir
X
Xprints a directory listing and then returns to GNUTEX.
X
X$ is accepted as a synonym for ! in VMS.
SHAR_EOF
fi # end of overwriting check
if test -f 'start_up'
then
	echo shar: will not over-write existing file "'start_up'"
else
sed 's/^X//' << \SHAR_EOF > 'start_up'
XWhen GNUTEX is run, it looks for an initialization file to execute.
XThis file is called '.gnutex' on Unix systems, and 'GNUTEX.INI' on
Xother systems.  If this file is not found in the current directory,
Xthe program will look for it in your home directory (under MS-DOS, the
Xenvironment variable GNUTEX should contain the name of this
Xdirectory).
X
XIf this file is found, GNUTEX executes the commands in this file.
XThis is most useful for setting your terminal type and defining any
Xfunctions or variables which you use often.  The variable 'pi' is
Xalready defined for you.
SHAR_EOF
fi # end of overwriting check
if test -f 'quit'
then
	echo shar: will not over-write existing file "'quit'"
else
sed 's/^X//' << \SHAR_EOF > 'quit'
X'quit' is a synonym for 'exit'.  See 'exit'.
SHAR_EOF
fi # end of overwriting check
if test -f 'exit'
then
	echo shar: will not over-write existing file "'exit'"
else
sed 's/^X//' << \SHAR_EOF > 'exit'
X'exit', 'quit' and your computer's END-OF-FILE character will
Xexit GNUTEX.  All these commands will clear the output device
X(as the 'clear' command does) before exiting.
SHAR_EOF
fi # end of overwriting check
if test -f 'load'
then
	echo shar: will not over-write existing file "'load'"
else
sed 's/^X//' << \SHAR_EOF > 'load'
XThis command executes each line of the specified input file 
Xas if it had been typed in interactively.  Files created by the 'save' 
Xcommand can later be 'load'ed.  Any text file containing valid commands
Xcan be created and then executed by the 'load' command.  Files being
X'load'ed may themselves contain 'load' commands.  
X
XThe 'load' command must be the last command on the line. 
X        
XSyntax:     load <input-file>
X
XThe name of the input file must be enclosed in quotes.
SHAR_EOF
fi # end of overwriting check
if test -f 'latex'
then
	echo shar: will not over-write existing file "'latex'"
else
sed 's/^X//' << \SHAR_EOF > 'latex'
XDocumentation for the LATEX extensions to gnuplot (gnutex) (updated 11/4/88):
X
XTo run gnutex, type
X   /usr/local/bin/gnutex
XSee /usr/local/public/doc/gnutex/* for examples and help.
X
XTo use the LaTeX facilities of gnutex, the first command to gnutex 
Xshould be 
X    set terminal latex
Xand the output of latex should be directed to a file, for example,
X    set output "plot.tex"
XThis may be anything you like but it should have a ".tex" extension,
Xof course. Then the size of the plot should be given, eg
X    set size 5, 4
Xtells gnutex to use a 5 inch wide by 4 inch high box for the plot.
XThis is the size of the actual plotting area; labels (see below) will
Xextend outside of this size.
X
XWhen finished, the file will contain all of the plots you have
Xspecified (you probably only want one plot per file). This file can
Xthen be used in a LaTeX document, for example,
X    \begin {figure}
X    	   \input{plot}
X    \end {figure}
XThis puts the plot into a figure. 
X
XOther than the above, gnutex acts much as gnuplot used to do. The plot
Xcommand will do its usual thing, but since TeX cannot draw straight
Xlines with arbitrary slopes, and runs out of memory if lines are
Xapproximated by a series of many tiny dots, lines are drawn as a
Xseries of dots. The usual symbols are plotted for the "with points"
Xlinestyle. User-defined styles are described below. 
X
XNOTE: Linestyles may no longer be abbreviated, for example, "p" for
X"points", "l" for "lines", and "linesp" for "linespoints". The full
Xword must be written out.
X
XThe plot is also labeled in a variety of ways.  The ticks on the x
Xand y axes are labeled with the appropriate numbers. The axes may be
Xlabeled and a title provided for the plot with new 'set' commands.
XThe labels in effect at the time of the "plot" command are used, so
Xthey should be set before the plot. Once set, they retain their values
Xuntil explicitly changed. For example,
X    set title "This is the title of the plot"
X    set xlabel "This is the x axis"
X    set ylabel "This is the y axis"
Xwill label the top, bottom, and left sides of the plot, respectively.
XThese can be more sophisticated, for example,
X    set title "This is a very long title\\because it has\\three lines"
X    set xlabel "This is the $x$ axis\\with more than two\\lines in the label"
X    set ylabel "This is a longer\\version of\\the $y$ axis"
XHere there are line breaks, and math mode is used to make the 'x' and
X'y' look like variables. The line breaks are particularly useful for 
Xthe y axis label.
X
XIf the ylabel is not coming out quite right (too close to the plot),
Xits position may be adjusted with a second parameter, such as
X    set ylabel "This is the y axis" 2
XThis will slide the y label about 2 characters further left (away from
Xthe plot). Positive and negative integers are allowed.
X
XSometimes the x- or y-axis numbers really don't mean anything, and you
Xwould rather not have the numbers and tics printed on the axis. If
Xthis is the case, insert a
X    set noxtics
Xand/or
X    set noytics
Xbefore the plot command. To turn them back on use
X    set xtics
X    set ytics
X
XThe tics on both axes are labelled with a format "$%g$", which uses
Xthe general-purpose printf format and math mode to format the number.
XIf you want to change this, use the "set format" command:
X    set format "format-string"
X    set format <axis> "format-string"
Xwhere <axis> is 'x', 'y', or 'xy'. Using 'xy' is the same as using
Xnothing at all, as in the first form. This sets the format string to
Xbe used for the given axis (axes). For example, you may prefer
X"$%3.1f$" (note that math mode almost always looks better, but is not
Xnecessary). Or maybe "$%3.0f \mu$sec", or "$%5.2 \cdot 10^{-3}$". Use
Xyour imagination, but restrict yourself to the f, e, and g formats, as
Xthe number is a double-precision number, and the other formats
X(d,o,x,u,c,s) will not work correctly.
X
X
XPlotting a Key:
X  If you wish a key describing the plots to be made, use the "key" command: 
X	key x,y "description1" w <style1> [, "description2" w <style2>"] ...
X
XThe key command looks a lot like a plot command. The coordinates x,y
Xspecify the location of the key on the plot (see below).  The key is
Xdrawn as a sequence of lines, with one plot described on each line. On
Xthe left-hand side of each line is a representation that attempts to
Xmimic the way the curve is plotted (eg, a bunch of dots for a line,
Xthe point symbol for a point, etc). On the right side of each line is
Xthe text "description" given in the command. The lines are vertically
Xarranged so an imaginary straight line divides the left- and
Xright-hand sides of the key. It is the x-coordinate of this line that
Xyou specify with the x in the key command; the y in the key command is
Xthe bottom of the key.
X
XFor example, the plot command
X	plot "foo" w points, "bar" w lines, "funky" w linespoints
Xfollowed by
X	key 5,5 "This is foo" w points, "This is bar" w lines, \
X		"This is funky" w linespoints
Xwould give us a key that looks (roughly) like this:
X	    <> This is foo
X	.....  This is bar
X	...+.. This is funky
X(The <> is a diamond).
X
XAny styles may be used in the key entries, including user-defined
Xstyles. For the points and linespoints styles, the point type plotted
Xis determined in the same way as in the plot command, so your key
Xentries should be in the same order as in the plot command. Note that
Xa key entry with an empty (ie "") description will not be included in
Xthe key, but may be included to affect the point-type determination.
XFor example, if you didn't want to key the "foo" curve above, but you
Xwanted "funky" to look right, the key command is
X	key 5,5 "" w points, "This is bar" w lines, \
X		"This is funky" w linespoints
Xand gives us a key that looks (roughly) like this:
X	.....  This is bar
X	...+.. This is funky
X
XThe key is fairly rough at this time and I may find ways to make it
Xlook better. Suggestions welcome.
X
X
XUser-defined linestyles:
X  If you find the "dot" approximation to lines to be inadequate, or
Xdesire your different curves on the same plot to have different
Xstyles, then you can define your own style (up to 16 may be defined).
XA style may be defined at any time with a command of the form
X	   set style <name> <point>
Xor
X	   set style <name> <spacing> <dot>...
Xor
X	   set style <name> <point> <spacing> <dot>...  
X
XThe first form defines a style similar to "points", the second similar
Xto "lines" and the third to "linespoints". The <name> is any
Xidentifier, just as with user-defined variables and functions (it may
Xnot be lines, points, impulses, or linespoints). To use the style,
Xsimply use the <name> where you would use any of the standard
Xlinestyle names: "with <name>", "set data style <name>", or "set
Xfunction style <name>".
X
XThe <point> is a quoted string of LaTeX source which describes text to
Xbe plotted at each point. Picture-mode and math-mode commands are the
Xmost useful.  For example, "\circle*{100}" draws a disk 1pt in
Xdiameter at each data point (the units of picture coordinates in use
Xare 1/100 point). "$\Diamond$" produces a large diamond symbol.
X
XThe <spacing> and <dot> arguments define a line in terms of a sequence
Xof "dots" to be output every <spacing> points along the line to be
Xplotted. <spacing> is a real number whose units are points. Each dot
X(up to 5 dots are allowed) is a quoted string of LaTeX text, as with
Xthe point above. The dots are plotted in rotation along the whole
Xcurve. 
X
XThus, to simulate a linespoints linestyle with alternating big and
Xlittle dots every 4 points the curve but to use a plus sign at each
Xdata point, 
X	   set style mine "$+$" 4 "\circle*{100}" "\circle*{200}"
X
XThe default style is as if 
X	   set style lines 2 "\circle*{1}"
X    	   set style linespoints <varies> 2 "\circle*{1}"
XHad been executed. (The smallest circle that will be drawn is about
X100 units; smaller sizes as this one will use that smallest size).
XLinespoints is special in that its points vary with each curve on the
Xplot, as with classic gnutex. This is not possible to embody in a
Xsingle user-defined linestyle.
X
XLabeling Curves:
XArbitrary labels may be placed on the most recent plot, using the new
X"label" command. The syntax is
X    label x,y "text"
Xwhere x,y is some coordinate in your plot's coordinate system (the
Xcommas are important). The text is any arbitrary LaTeX input, any will
Xbe processed in LR mode.  The text is centered at the point x,y. The
Xlabel command should follow the plot command. Any number of labels may
Xbe placed.
X
XIf you want to adjust the way the label is positioned with respect to
Xthe point x,y, add another parameter:
X    label x,y "text" pos
Xwhere pos is one of r,l,t,b,lt,lb,rt,rb indicating that the text
Xshould be placed so that the point is at the right center, left
Xcenter, top center, bottom center, left top corner, etc. 
X
XAn arrow can be drawn out from the point simply by giving its
Xlength in problem coordinates, after the pos:
X    label x,y "text" pos length
XThe length is defined to be the HORIZONTAL extent of the arrow, unless
Xthe arrow is vertical, in which case it is the vertical extent of the
Xarrow.  The arrow is drawn AWAY FROM the text; for example, if pos is
Xlt, then away is defined to be up and to the left. If it is b, away is
Xdefined to be down. This allows for eight different directions of
Xarrows.
X
XFurther control over the slope of the arrow can be gained by
Xspecifying exactly the slope you want. You should read about vectors
Xon page 198 in the LaTeX manual. The command looks like
X    label x,y "text" pos length, h_slope, v_slope
X(the commas are important). The h_slope and v_slope are integers in
Xthe range -4 to 4, which specify the slope of the line (run, rise).
XA horizontal line is 1,0, vertical is 0,1. The two numbers may not
Xhave a common divisor other than +1 or -1.
X
XLabels outside of the plotted boundaries are permitted but may
Xinterfere with axes labels or other text; use at your own risk.
X
XOther
X-----
X
XGnutex normally clips (actually, does not plot at all) data points
Xthat fall within but too close to the boundaries (this is so the large
Xsymbols used for points will not extend outside the boundary lines).
XWith the user-defined styles it is often desirable to make smaller
Xpoints, and thus points near the boundaries may be plotted. To turn
Xoff clipping, use
X    set noclip
XTo turn it back on, use
X    set clip
XThe default is 'clip'. Without clipping you may have points near the
Xboundaries that look bad; try adjusting the x and y ranges.
X
XComments:
X  Comments are now supported: a # may appear in most places in a line
Xand gnutex will ignore the rest of the line. It will not have this
Xaffect inside quotes, inside numbers (incl. complex numbers), inside
Xcommand substitutions, etc. In short, it works anywhere it makes sense
Xto work.
X
XPlease send bug reports and suggestions to dfk@cs.duke.edu.
SHAR_EOF
fi # end of overwriting check
if test -f 'substitution'
then
	echo shar: will not over-write existing file "'substitution'"
else
sed 's/^X//' << \SHAR_EOF > 'substitution'
XCommand-line subsitution is specified by a system command enclosed in
Xbackquotes (``).   This command is spawned and the output it produces
Xreplaces the name of the command (and backquotes) on the command line.
X
XNewlines in the output produced by the spawned command are replaced with
Xblanks.
X
XCommand-line substitution can be used anywhere on the GNUTEXcommand line. 
X
XExamples:
X
Xa(x) = `leastsq`                ; substitutes "`leastsq`" with output produced
X                    by a program named leastsq.
Xa(x) = `run leastsq.exe`        ; same but for VMS.
SHAR_EOF
fi # end of overwriting check
if test -f 'user_defined'
then
	echo shar: will not over-write existing file "'user_defined'"
else
sed 's/^X//' << \SHAR_EOF > 'user_defined'
XYou may define your own functions and variables.  User-defined functions and
Xvariables may be used anywhere. 
X
XUser-defined function syntax:
X    <function-name> ( <dummy-var> ) =  <expression>
X
XWhere <expression> is defined in terms of <dummy-var>.
X
XUser-defined variable syntax:
X    <variable-name> = <constant-expression>
X
XExamples:
X    w = 2
X	q = floor(tan(pi/2 - 0.1))
X    f(x) = sin(w*x)
X    sinc(x) = sin(pi*x)/(pi*x)
X    delta(t) = (t == 0)
X    ramp(t) = (t > 0) ? t : 0
X
XThe variable 'pi' is already defined for you.
X
XSee 'show functions' and 'show variables'. See 'latex' for defining
Xyour own linestyles. 
SHAR_EOF
fi # end of overwriting check
cd ..
if test -f 'Patch3-rm'
then
	echo shar: will not over-write existing file "'Patch3-rm'"
else
sed 's/^X//' << \SHAR_EOF > 'Patch3-rm'
X#!/bin/csh -f
X# Execute this file after applying gnutex.patch3 to remove files that
X# are no longer part of the distribution
X
Xif (`cat PATCHLEVEL` == 3) then
X   set verbose
X   rm -f 1.dat 2.dat 3.dat gnutex.1 pic.tex simple.demo try
X   rm -f try.tek doc/3.dat doc/LATEX-doc doc/LATEX-new doc/README
X   rm -f doc/gnu.input doc/pic.tex doc/plot.tex help/.MANUAL
X   rm -f help/expressions/.HLP
X   rm -f Patch3-rm
Xendif
SHAR_EOF
chmod +x 'Patch3-rm'
fi # end of overwriting check
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Makefile for gnutex
X#   A plotting program supporting LaTeX output
X#   David Kotz
X#   Duke University
X#   dfk@cs.duke.edu
X#
X# derived from gnuplot, originally by Colin Kelley and Thomas Williams
X#
X# Adjust some of the items below, as necessary, and type 'make'.
X# Try 'make demo' after gnutex has been made.
X#
X
X# where to install on 'make install'
XDESTDIR=/usr/local/bin/
XMANDIR=/usr/man/manl
X
X# -lplot iff UNIXPLOT you have -DUNIXPLOT
XLIBS = -lm -lplot
X
X# -DVFORK iff vfork() supported
XCFLAGS = -DVFORK
X
X# -D<terminal> only if you wish to support <terminal>
X# -DAED        Aed767
X# -DHP75       HP7580, and probably other HPs
X# -DQMS        QMS/QUIC laserprinter (Talaris 1200 and others)
X# -DREGIS      ReGis graphics (vt220, vt240, Gigis...)
X# -DTEK        Tektronix 4010, and probably others
X# -DHALFTEK    Tektronix 4010 (top/bottom half of screen)
X# -DUNIXPLOT   unixplot
X# -DLATEX	  	LaTeX output
X
X#TERMFLAGS = -DQMS -DTEK -DHALFTEK -DUNIXPLOT -DLATEX
XTERMFLAGS =  -DTEK -DUNIXPLOT -DLATEX
X#TERMFLAGS =   -DLATEX
X
X# Your favorite tags program
XTAGS=etags
X#TAGS=ctags
X
XOBJS = plot.o scanner.o parse.o command.o eval.o standard.o internal.o util.o\
X   	graphics.o term.o misc.o version.o
X
XSRC = plot.h command.c eval.c graphics.c internal.c misc.c \
X	parse.c plot.c scanner.c standard.c term.c util.c version.c
X
Xall: gnutex
X
Xinstall: gnutex 
X	install -c -s gnutex $(DESTDIR)gnutex
X	install -c lasergnu $(DESTDIR)lasergnu
X	install -m 444 doc/gnutex.1 $(MANDIR)/gnutex.l
X	install -m 444 doc/lasergnu.1 $(MANDIR)/lasergnu.l
X
Xgnutex: $(OBJS)
X	cc $(CFLAGS) $(OBJS) $(LIBS) -o gnutex
X
Xterm.o: term.c 
X	cc $(CFLAGS) $(TERMFLAGS) -c term.c
X
X$(OBJS): plot.h
X
X# Make a very simple demo plot
Xdemo:
X	(cd doc/example; make)
X
X# Make a patch file, diffing this directory with ../gnutex.old
X# To apply the patch, use patch -p < ../gnutex.patch
Xpatch:
X	-diff -cr ../gnutex.old . > ../gnutex.patch
X
XTAGS: $(SRC)
X	$(TAGS) $(SRC)
X
Xclean:
X	rm -f *.o *~ core
X
Xspotless:
X	rm -f *.o *~ core gnutex TAGS
X
SHAR_EOF
fi # end of overwriting check
if test -f 'PATCHLEVEL'
then
	echo shar: will not over-write existing file "'PATCHLEVEL'"
else
sed 's/^X//' << \SHAR_EOF > 'PATCHLEVEL'
X3
SHAR_EOF
fi # end of overwriting check
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XThis directory contains the sources for gnuplot, a general-purpose
Xplotting program, as modified by David Kotz at Duke University in
X1987-1988. At this point it is likely out of date with the current
Xversion of gnuplot; I may try to synchronize them someday, but the
Xmods for Latex support and other support are significant. I have
Xgenerally tried to retain the style of the original and to modify as
Xlittle as possible to make this possible. 
X
XI have not tried compiling this for VMS, and only use the Latex and
Xtektronix drivers.
X
XDocumentation is in 
Xgnutex.1   - man page for gnutex
Xdoc        - documentation and examples about LATEX additions
Xhelp       - help files for gnuplot and gnutex
X
XSample gnutex input files are "try" and "try.tek" (a non-LATEX
Xversion). Type "gnutex<try" then "latex pic" to see what it looks
Xlike.
X
Xlasergnu is a system-dependent shell script to gnutex a simple plot
Xand send it to the textronix-compatible imagen laser printer. Good
Xluck.
X
XPLEASE send comments, suggestions, bugs etc to dfk@cs.duke.edu. I make
Xno guarantees about maintenance or updates but will try to put out
Xpatches as things change. I consider this program to still be
Xdeveloping.
X
XMAILINGS: If you want to be on my gnutex mailing list send me a note
Xwith a good return address. This is not a two-way mailing list; I'm
Xnot going to moderate a group here! This will provide a way for me to
Xannounce updates and poll the users about things.
X
XCOPYRIGHT: 
X  You may use this program as you wish, as far as I'm concerned, and
Xas long as you follow the usage statement given by the gnuplot authors
Xin each file.
X
XPATCHES:
Xpatch1: Enhancement to add "set format" command. See help/set-show/format.
Xpatch2: Small change to source so VMS compilers accept it. 
Xpatch3: New manual written (see doc/). Several small but annoying bugs
Xfixed.  Note that start-up initialization file is no long ".gnuplot"
Xbut ".gnutex". 
X
XDavid Kotz
XNovember 4, 1988
XDepartment of Computer Science, Duke University, Durham, NC 27706
XARPA:	dfk@cs.duke.edu
XCSNET:	dfk@duke        
XUUCP:	decvax!duke!dfk
X
SHAR_EOF
fi # end of overwriting check
if test -f 'README.gnuplot'
then
	echo shar: will not over-write existing file "'README.gnuplot'"
else
sed 's/^X//' << \SHAR_EOF > 'README.gnuplot'
XGNUPLOT has been tested on a Pyramid 90x (ucb 4.2 and att V),
Xa VAX 8200 (VMS 4.3), IBM PC's and AT's (MS-DOS 3.1, Microsoft C 4.0).
XThe code is written with portability in mind, and it passes lint!
XIf you have problems, send mail to vu-vlsi!plot.  And please send
Xany modifications you make so they can be #ifdef'd into later releases.
X
XThese #defines should be checked before compilation:
X
XVFORK       Makefile        define if you've got vfork() system call
Xvms         Makefile        define if compiling under VMS;
X                              automatically defined by DEC C
XPC          Makefile        define if compiling on a PClone
XMSDOS       Makefile        define if compiling under MSDOS;
X                              automatically defined by Microsoft C 4.0
XAED         Makefile        define these if you want this terminal driver
XHP75           .              included
XQMS            .
XREGIS          .
XTEK            .
XUNIXPLOT       .
X
XCGA            .            same, but only if PC is defined
XCORONA         .
XEGA            .
X
XHUGE        plot.h          define to be largest double if not defined
X                              in <math.h>
XHELP        plot.h          program run by 'help' command
XSHELL       plot.h          default shell to spawn if SHELL environment
X                              variable not found at run-time
X
XTo compile:
X
Xunder UNIX:  type 'make'
X
Xunder VMS:  type '@compile', then '@link'.  Use the 'vmshelp.csh' script
Xto convert the help files.  If you don't have access to a Unix machine,
Xsend us mail and we'll send you the VMS GNUPLOT.HLB.
X
Xunder MSDOS:  use 'make make.msc' for Microsoft C 4.0.  If you've got
Xanother compiler, you're on your own!
SHAR_EOF
fi # end of overwriting check
if test -f 'README.sun4'
then
	echo shar: will not over-write existing file "'README.sun4'"
else
sed 's/^X//' << \SHAR_EOF > 'README.sun4'
XPlease note that (at least in some versions of the Sun4 compiler or
Xstdio library), the following bugs exist. 
X
XBUG #1: This causes axes labels (in LATEX) and the plot ranges (the -l
Xoption) to be printed incorrectly for some numbers. The solution? Get
XSun to fix the bug, or use %f or %e formats (see the "set format"
Xcommand). This has been fixed in SunOS 4.0. For the -l option plot
Xranges, be wary that they may be incorrect.
X
XDFK 11-30-88
X-------------------------------------
XOn a Sun3, it works correctly:
X
XScript started on Wed Nov 30 13:58:56 1988
Xgrad2 dfk> more test.c
X/* Program to demonstrate bug in printf for SunOS Sys4-3.2 on Sun4 */
X/* David Kotz, Duke University */
Xmain()
X{
X    printf("Should be 200000: %g\n", 200000.);
X    printf("Should be 200: %-.3g\n", 200.);
X    printf("Will be 200: %g\n", 200.);
X}
Xgrad2 dfk> cc -o t test.c
Xgrad2 dfk> t
XShould be 200000: 200000
XShould be 200: 200
XWill be 200: 200
Xgrad2 dfk> 
Xscript done on Wed Nov 30 13:59:24 1988
X
XBut on a Sun4, it does not work correctly:
X
XScript started on Wed Nov 30 13:56:59 1988
Xromeo dfk> more test.c
X/* Program to demonstrate bug in printf for SunOS Sys4-3.2 on Sun4 */
X/* David Kotz, Duke University */
Xmain()
X{
X    printf("Should be 200000: %g\n", 200000.);
X    printf("Should be 200: %-.3g\n", 200.);
X    printf("Will be 200: %g\n", 200.);
X}
Xromeo dfk> cc -o t test.c
Xromeo dfk> t
XShould be 200000: 2
XShould be 200: 2
XWill be 200: 200
Xromeo dfk> 
Xscript done on Wed Nov 30 13:57:22 1988
X
X----------------------------------------------------------------------
XBUG #2: The sscanf routine incorrectly parses "00 12" with the format
X"%f %f" and reads 0 and 0 instead of 0 and 12. This affects data
Xinput. If your data file contains x coordinates that are zero but are
Xspecified like '00' or '000' etc, then you wil read the wrong y
Xvalues. Check your data files or don't use a Sun4 until they fix the
Xbug. Example program below:
X
X#include <stdio.h>
Xmain()
X{
X    char *line1="0  12 34";
X    char *line2="00 12 34";
X    float x,y,z;
X    int n;
X
X    n = sscanf(line1, "%f %f %f", &x, &y, &z);
X    printf("line is '%s', x is %f, y is %f, z is %f, n is %d\n",
X		 line1, x, y, z, n);
X
X    n = sscanf(line2, "%f %f %f", &x, &y, &z);
X    printf("line is '%s', x is %f, y is %f, z is %f, n is %d\n", 
X		 line2, x, y, z, n);
X}
X
SHAR_EOF
fi # end of overwriting check
if test -f 'command.c'
then
	echo shar: will not over-write existing file "'command.c'"
else
sed 's/^X//' << \SHAR_EOF > 'command.c'
X/*
X *
X *    G N U P L O T  --  command.c
X *
X *  Copyright (C) 1986 Thomas Williams, Colin Kelley
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X/*
X * Modifications for LaTeX and other support by David Kotz, 1988.
X * Department of Computer Science, Duke University, Durham, NC 27706.
X * Mail to dfk@cs.duke.edu.
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "plot.h"
X
X#ifndef STDOUT
X#define STDOUT 1
X#endif
X
X/*
X * global variables to hold status of 'set' options
X *
X */
XBOOLEAN			autoscale_x = TRUE;
XBOOLEAN			autoscale_y = TRUE;
XBOOLEAN			autoscale_lx = TRUE; /* local to this plot */
XBOOLEAN			autoscale_ly = TRUE; /* local to this plot */
Xenum PLOT_STYLE data_style	= POINTS,
X				func_style	= LINES;
XBOOLEAN			log_x		= FALSE,
X				log_y		= FALSE;
XFILE*			outfile;
Xchar			outstr[MAX_ID_LEN+1] = "STDOUT";
Xint				samples		= SAMPLES;
Xint				term		= 0;				/* unknown term is 0 */
Xdouble			xmin		= -10,
X				xmax		= 10,
X				ymin		= -10,
X				ymax		= 10;
Xdouble			zero = ZERO;			/* zero threshold, not 0! */
X
XBOOLEAN xtics = TRUE;
XBOOLEAN ytics = TRUE;
X
XBOOLEAN clipping = TRUE;
X
XBOOLEAN screen_ok;
XBOOLEAN term_init;
XBOOLEAN undefined;
X
Xchar title_string[MAX_LINE_LEN] = "";
Xchar xlabel_string[MAX_LINE_LEN] = "";
Xchar ylabel_string[MAX_LINE_LEN] = "";
Xchar xformat[MAX_ID_LEN] = "$%g$";
Xchar yformat[MAX_ID_LEN] = "$%g$";
Xint y_skip_factor = 0;
Xdouble plot_width = 4;		/* width  in inches, for latex */
Xdouble plot_height = 3;		/* height in inches, for latex */
X
X/*
X * instead of <strings.h>
X */
X
Xchar *gets(),*getenv();
Xchar *strcpy(),*strcat();
X
Xdouble magnitude(),angle(),real(),imag();
Xstruct value *const_express(), *pop(), *complex();
X
X
Xextern struct vt_entry vt[];
Xextern struct st_entry st[];
Xextern struct udft_entry udft[];
Xextern struct termentry term_tbl[];
Xextern int next_style;
X
Xchar input_line[MAX_LINE_LEN],dummy_var[MAX_ID_LEN + 1];
Xstruct at_type *curr_at;
Xint c_token;
Xint next_value = (int)NEXT_VALUE,next_function = 0,c_function = 0;
Xint num_tokens;
X
Xstruct curve_points plot[MAX_PLOTS];
X
Xstatic char help[80] = HELP;
X
X#ifdef MSDOS
X#include <process.h>
X#endif /* MSDOS */
X
X#ifdef vms
X#include <descrip.h>
X#include <rmsdef.h>
X#include <errno.h>
X
Xextern lib$get_input(), lib$put_output();
X
Xint vms_len;
X
Xunsigned int status[2] = {1, 0};
X
X$DESCRIPTOR(prompt_desc,PROMPT);
X$DESCRIPTOR(line_desc,input_line);
X$DESCRIPTOR(null_desc,"");
X
X$DESCRIPTOR(help_desc,help);
X$DESCRIPTOR(helpfile_desc,"GNUPLOT$HELP");
X
Xstruct dsc$descriptor_s *cmd_ptr;
X
X#endif
X
Xcom_line()
X{
X#ifdef vms
X
X	switch(status[1] = lib$get_input(&line_desc, &prompt_desc, &vms_len)){
X		case RMS$_EOF:
X			done(IO_SUCCESS);	/* ^Z isn't really an error */
X			break;
X		case RMS$_TNS:			/* didn't press return in time */
X			vms_len--;		/* skip the last character */
X			break;			/* and parse anyway */
X		case RMS$_BES:			/* Bad Escape Sequence */
X		case RMS$_PES:			/* Partial Escape Sequence */
X			sys$putmsg(status);
X			vms_len = 0;		/* ignore the line */
X			break;
X		case SS$_NORMAL:
X			break;			/* everything's fine */
X		default:
X			done(status[1]);	/* give the error message */
X	}
X
X	if (vms_len && (input_line[0] == '!' || input_line[0] == '$')) {
X		if (vms_len == 1)	/* spawn an interactive shell */
X			cmd_ptr = &null_desc;
X		else {
X			cmd_ptr = &line_desc;
X			input_line[0] = ' ';	/* an embarrassment, but... */
X		}
X
X		if ((status[1] = lib$spawn(cmd_ptr)) != SS$_NORMAL) {
X			sys$putmsg(status);
X		}
X		(void) putchar('\n');
X
X	} else {
X		input_line[vms_len] = '\0';
X
X#else
X		/* not VMS */
X	fprintf(stderr,PROMPT);
X#ifdef MSDOS
X	input_line[0] = MAX_LINE_LEN - 2;
X	cgets(input_line);			/* console input so CED will work */
X	(void) putc('\n',stderr);
X	if (input_line[2] == 26) {
X		(void) putc('\n',stderr);		/* end-of-file */
X		done(IO_SUCCESS);
X	}
X	{
X		register int i = -1;
X		do				/* yuck!  move everything down two characters */
X			i++;
X		while (input_line[i] = input_line[i+2]);
X	}
X
X#else /* MSDOS */
X		/* plain old Unix */
X     {
X	    int start = 0, left = MAX_LINE_LEN;
X	    int more = TRUE;
X	    int len;
X
X	    while (more) {
X		   if (!(int) fgets(&(input_line[start]), left, stdin)) {
X			  (void) putc('\n',stderr);		/* end-of-file */
X			  input_line[start] = '\0';
X			  if (start > 0) /* don't quit yet - process what we have */
X			    more = FALSE;
X			  else
X			    done(IO_SUCCESS);
X		   } else {
X			  len = strlen(input_line) - 1;
X			  if (input_line[len] == '\n') { /* remove any newline */
X				 input_line[len] = '\0';
X				 len--;
X			  } else if (len+1 >= left)
X			    int_error("Input line too long",NO_CARET);
X				 
X			  if (input_line[len] == '\\') { /* line continuation */
X				 start = len;
X				 left -= len;
X			  } else
X			    more = FALSE;
X		   }
X	    }
X	}
X#endif /* MSDOS */
X
X	screen_ok = TRUE; /* so we can flag any new output */
X
X	if (input_line[0] == '!') {
X		if (system(input_line + 1))
X			os_error("system() failed",NO_CARET);
X	} else {
X#endif /* vms */
X		do_line();
X	}
X}
X
X
X
Xdo_line()  /* also used in load_file */
X{
X	num_tokens = scanner(input_line);
X	c_token = 0;
X	while(c_token < num_tokens) {
X		command();
X		if (c_token < num_tokens)	/* something after command */
X			if (equals(c_token,";"))
X				c_token++;
X			else
X				int_error("';' expected",c_token);
X	}
X}
X
X
X
Xcommand()
X{
Xregister int tsamp,len;
Xregister FILE *f;
Xstruct value a;
Xstatic char sv_file[MAX_ID_LEN+1];
Xint style;
Xregister int i;
X
X			/* string holding name of save or load file */
X
X	dummy_var[0] = '\0';		/* no dummy variable */
X
X	if (is_definition(c_token))
X		define();
X	else if (equals(c_token,"help") || equals(c_token,"?")) {
X		c_token++;
X		len = sizeof(HELP)-1;
X		help[len] = '\0';		/* remove previous help arguments */
X		while (!(END_OF_COMMAND)) {
X			help[len] = ' ';   /* put blank between help segments */
X			copy_str(help+len+1,c_token++);
X			len = strlen(help);
X		}
X#ifdef vms
X		help_desc.dsc$w_length = len;
X		if ((vaxc$errno = lbr$output_help(lib$put_output,0,&help_desc,
X			&helpfile_desc,0,lib$get_input)) != SS$_NORMAL)
X				os_error("can't open GNUPLOT$HELP");
X#else /* vms */
X		if (system(help))
X			os_error("can't spawn help");
X#endif /* vms */
X		screen_ok = FALSE;
X		c_token++;
X	}
X	else if (almost_equals(c_token,"pr$int")) {
X		c_token++;
X		(void) const_express(&a);
X		(void) putc('\t',stderr);
X		show_value(stderr,&a);
X		(void) putc('\n',stderr);
X		screen_ok = FALSE;
X	}
X	else if (almost_equals(c_token,"p$lot")) {
X		c_token++;
X		plotrequest();
X	}
X	else if (almost_equals(c_token,"la$bel")) {
X		c_token++;
X		labelrequest();
X	}
X	else if (almost_equals(c_token,"k$ey")) {
X		c_token++;
X		keyrequest();
X	}
X	else if (almost_equals(c_token,"se$t")) {
X		if (almost_equals(++c_token,"t$erminal")) {
X			c_token++;
X			if (END_OF_COMMAND)
X				list_terms();
X			else
X				term = set_term(c_token);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"sa$mples")) {
X			c_token++;
X			tsamp = (int)magnitude(const_express(&a));
X			if (tsamp < 1) 
X				int_error("sampling rate must be > 0; sampling unchanged",
X					c_token);
X			else {
X				samples = tsamp;		
X				pointmem(samples);
X			}
X		}
X		else if (almost_equals(c_token,"o$utput")) {
X			c_token++;
X			if (END_OF_COMMAND) {	/* no file specified */
X				(void) fclose(outfile);
X				outfile = fdopen(dup(STDOUT), "w");
X				if (term != 0)
X				  (*term_tbl[term].reset)();
X				term_init = FALSE;
X				(void) strcpy(outstr,"STDOUT");
X			} else if (!isstring(c_token)) 
X				int_error("expecting filename",c_token);
X			else {
X				quote_str(sv_file,c_token);
X				if (!(f = fopen(sv_file,"w"))) {
X				  os_error("cannot open file; output not changed",c_token);
X				}
X				if (term != 0)
X				  (*term_tbl[term].reset)();
X				term_init = FALSE;
X
X				(void) fclose(outfile);
X				outfile = f;
X
X				outstr[0] = '\'';
X				strcat(strcpy(outstr+1,sv_file),"'");
X			} 
X			c_token++;
X		}
X		else if (almost_equals(c_token,"a$utoscale")) {
X		    c_token++;
X		    if (END_OF_COMMAND) {
X			   autoscale_x = autoscale_y = TRUE;
X		    } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
X			   autoscale_x = autoscale_y = TRUE;
X			   c_token++;
X		    } else if (equals(c_token, "x")) {
X			   autoscale_x = TRUE;
X			   c_token++;
X		    } else if (equals(c_token, "y")) {
X			   autoscale_y = TRUE;
X			   c_token++;
X		    }
X		} 
X		else if (almost_equals(c_token,"noa$utoscale")) {
X		    c_token++;
X		    if (END_OF_COMMAND) {
X			   autoscale_x = autoscale_y = FALSE;
X		    } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
X			   autoscale_x = autoscale_y = FALSE;
X			   c_token++;
X		    } else if (equals(c_token, "x")) {
X			   autoscale_x = FALSE;
X			   c_token++;
X		    } else if (equals(c_token, "y")) {
X			   autoscale_y = FALSE;
X			   c_token++;
X		    }
X		} 
X		else if (almost_equals(c_token,"nol$ogscale")) {
X			log_x = log_y = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"z$ero")) {
X			c_token++;
X			zero = magnitude(const_express(&a)); 
X		}
X		else if (almost_equals(c_token,"x$range")) {
X			c_token++;
X			if (!equals(c_token,"["))
X				int_error("expecting '['",c_token);
X			c_token++;
X			load_range(&xmin,&xmax);
X			autoscale_x = FALSE;
X			if (!equals(c_token,"]"))
X				int_error("expecting ']'",c_token);
X			c_token++;
X		}
X		else if (almost_equals(c_token,"y$range")) {
X			c_token++;
X			if (!equals(c_token,"["))
X				int_error("expecting '['",c_token);
X			c_token++;
X			load_range(&ymin,&ymax);
X			autoscale_y = FALSE;
X			if (!equals(c_token,"]"))
X				int_error("expecting ']'",c_token);
X			c_token++;
X		}
X		else if (almost_equals(c_token,"l$ogscale")) {
X			c_token++;
X			if (equals(c_token,"x")) {
X				log_y = FALSE;
X				log_x = TRUE;
X				c_token++;
X			}
X			else if (equals(c_token,"y")) {
X				log_x = FALSE;
X				log_y = TRUE;
X				c_token++;
X			}
X			else if (equals(c_token,"xy") || equals(c_token,"yx")) {
X				log_x = log_y = TRUE;
X				c_token++;
X			}
X			else
X				int_error("expecting 'x', 'y', or 'xy'",c_token);
X		}
X		else if (almost_equals(c_token,"d$ata")) {
X			c_token++;
X			if (!almost_equals(c_token,"s$tyle")) 
X				int_error("expecting keyword 'style'",c_token);
X			c_token++;
X			for (style = 0; style < next_style; style++) {
X			    if (equals(c_token, st[style].st_name)) {
X				   data_style = (enum PLOT_STYLE) style;
X				   break;
X			    }
X			}
X			if (style == next_style) 
X			  int_error("unknown style - type 'show style'", c_token);
X			c_token++;
X		}
X		else if (almost_equals(c_token,"f$unction")) {
X			c_token++;
X			if (!almost_equals(c_token,"s$tyle")) 
X				int_error("expecting keyword 'style'",c_token);
X			c_token++;
X			for (style = 0; style < next_style; style++) {
X			    if (equals(c_token, st[style].st_name)) {
X				   func_style = (enum PLOT_STYLE) style;
X				   break;
X			    }
X			}
X			if (style == next_style) 
X			  int_error("unknown style - type 'show style'", c_token);
X			c_token++;
X		}
X		else if (almost_equals(c_token,"st$yle")) {
X			c_token++;
X			if (END_OF_COMMAND)
X			  int_error("expecting name of new style", c_token);
X			/* get the name and definition of the style and add to table  */
X			c_token = add_style();
X		}
X		else if (almost_equals(c_token,"xl$abel")) {
X		    c_token++;
X		    if (!isstring(c_token)) 
X			 int_error("expecting x label string",c_token);
X		    else {
X			   quote_str(xlabel_string,c_token);
X		    }
X		    c_token++;
X		}
X		else if (almost_equals(c_token,"xt$ics")) {
X			xtics = TRUE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"noxt$ics")) {
X			xtics = FALSE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"yl$abel")) {
X		    c_token++;
X		    if (!isstring(c_token)) {
X			   int_error("expecting y label string",c_token);
X		    } else {
X			   quote_str(ylabel_string,c_token);
X			   c_token++;
X			   if (!END_OF_COMMAND) {  /* skip factor specified */
X				  y_skip_factor = (int)magnitude(const_express(&a));
X				  c_token++;
X			   }
X		    }
X		}
X		else if (almost_equals(c_token,"yt$ics")) {
X			ytics = TRUE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"noyt$ics")) {
X			ytics = FALSE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"fo$rmat")) {
X			BOOLEAN setx, sety;
X			c_token++;
X			if (equals(c_token,"x")) {
X			    setx = TRUE; sety = FALSE;
X			    c_token++;
X			}
X			else if (equals(c_token,"y")) {
X			    setx = FALSE; sety = TRUE;
X			    c_token++;
X			}
X			else if (equals(c_token,"xy") || equals(c_token,"yx")) {
X			    setx = sety = TRUE;
X			    c_token++;
X			}
X			else if (isstring(c_token)) {
X			    /* Assume he wants both */
X			    setx = sety = TRUE;
X			}
X			else
X				int_error("expecting 'x', 'y', or 'xy'",c_token);
X			if (!isstring(c_token))
X			  int_error("expecting format string",c_token);
X			else {
X			    if (setx)
X				 quote_str(xformat,c_token);
X			    if (sety)
X				 quote_str(yformat,c_token);
X			    c_token++;
X			}
X		}
X		else if (almost_equals(c_token,"ti$tle")) {
X		    c_token++;
X		    if (!isstring(c_token)) 
X			 int_error("expecting title string",c_token);
X		    else {
X			   quote_str(title_string,c_token);
X		    }
X		    c_token++;
X		}
X		else if (almost_equals(c_token,"si$ze")) {
X		    c_token++;
X		    plot_width = magnitude(const_express(&a));
X		    c_token++;
X		    plot_height = magnitude(const_express(&a));
X		    c_token++;
X		}
X		else if (almost_equals(c_token,"cl$ip")) {
X			clipping = TRUE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"nocl$ip")) {
X			clipping = FALSE;
X			c_token++;
X		} 
X		else
X			int_error("unknown set option (try 'help set')",c_token);
X	}
X	else if (almost_equals(c_token,"sh$ow")) {
X		if (almost_equals(++c_token,"f$unctions")) {
X			c_token++;
X			if (almost_equals(c_token,"s$tyle"))  {
X				fprintf(stderr,"\nfunctions are plotted with %s\n\n",
X					   st[(int)func_style].st_name);
X				screen_ok = FALSE;
X				c_token++;
X			 }
X			else 
X				view_functions();
X		}
X		else if (almost_equals(c_token,"v$ariables")) {
X			view_variables();
X			c_token++;
X		}
X		else if (almost_equals(c_token,"ac$tion_table") ||
X				 equals(c_token,"at") ) {
X			c_token++;
X			view_at();
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"d$ata")) {
X			c_token++;
X			if (!almost_equals(c_token,"s$tyle")) 
X				int_error("expecting keyword 'style'",c_token);
X			fprintf(stderr,"\ndata is plotted with %s\n\n",
X				   st[(int) data_style].st_name);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"x$range")) {
X			fprintf(stderr,"\nxrange is [%g : %g]\n\n",xmin,xmax);
X			screen_ok = FALSE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"y$range")) {
X			fprintf(stderr,"\nyrange is [%g : %g]\n\n",ymin,ymax);
X			screen_ok = FALSE;
X			c_token++;
X		} 
X		else if (almost_equals(c_token,"z$ero")) {
X			fprintf(stderr,"\nzero is %g\n\n",zero);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"sa$mples")) {
X			fprintf(stderr,"\nsampling rate is %d\n\n",samples);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"o$utput")) {
X			fprintf(stderr,"\noutput is sent to %s\n\n",outstr);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"t$erminal")) {
X			fprintf(stderr,"\nterminal type is %s\n\n",term_tbl[term].name);
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"au$toscale")) {
X			fprintf(stderr,"\nx autoscaling is %s\n\n",(autoscale_x)? "ON" : "OFF");
X			fprintf(stderr,"\ny autoscaling is %s\n\n",(autoscale_y)? "ON" : "OFF");
X			screen_ok = FALSE;
X			c_token++;
X		}
X		else if (almost_equals(c_token,"ve$rsion")) {
X			(void) putc('\n',stderr);
X			show_version(); 
X			c_token++; 
X		} 
X		else if (almost_equals(c_token,"l$ogscale")) {
X			if (log_x && log_y) 
X				fprintf(stderr,"\nlogscaling both x and y axes\n\n");
X			else if (log_x)
X				fprintf(stderr,"\nlogscaling x axis\n\n");
X			else if (log_y)
X				fprintf(stderr,"\nlogscaling y axis\n\n");
X			else 
X				fprintf(stderr,"\nno logscaling\n\n");
X			c_token++;
X		}
X		else if (almost_equals(c_token,"cl$ipping")) {
X			fprintf(stderr, "clipping is %s\n", clipping ? "ON" : "OFF");
X			c_token++;
X		}
X		else if (almost_equals(c_token,"xl$abel")) {
X		    c_token++;
X		    fprintf(stderr, "x axis label is '%s'\n", xlabel_string);
X		}
X		else if (almost_equals(c_token,"yl$abel")) {
X		    c_token++;
X		    fprintf(stderr, "y axis label is '%s', spacing factor %d\n",
X				  ylabel_string, y_skip_factor);
X		}
X		else if (almost_equals(c_token,"fo$rmat")) {
X			c_token++;
X			fprintf(stderr, "x-axis tic format is \"%s\"\n", xformat);
X			fprintf(stderr, "y-axis tic format is \"%s\"\n", yformat);
X		}
X		else if (almost_equals(c_token,"ti$tle")) {
X		    c_token++;
X		    fprintf(stderr, "title is '%s'\n", title_string);
X		}
X		else if (almost_equals(c_token,"si$ze")) {
X		    c_token++;
X		    fprintf(stderr, "plot size is %g\" width, %g\" high\n",
X				  plot_width, plot_height);
X		}
X		else if (almost_equals(c_token,"st$yle")) {
X		    c_token++;
X		    if (END_OF_COMMAND) {
X			   fprintf(stderr, "Available plot styles are:\n");
X			   for (style = 0; style < next_style; style++) {
X				  fprintf(stderr, "  %s\n", st[style].st_name);
X			   }
X			   fprintf(stderr, "For more info on style xxx type 'show style xxx'\n");
X		    } else {
X			   for (style = 0; style < next_style; style++) {
X				  if (equals(c_token, st[style].st_name))
X				    break;
X			   }
X			   if (style == next_style)
X				fprintf(stderr, "That style is not defined.\n");
X			   else {
X				  fprintf(stderr, "Style '%s': ", st[style].st_name);
X				  if (style <= FIXED_STYLES)
X				    printf("Built-in style\n");
X				  if (*st[style].st_point != '\0')
X				    fprintf(stderr, "Point symbol '%s'\n", 
X						  st[style].st_point);
X				  if (st[style].st_length > 0) {
X					 fprintf(stderr, "  Dot Sequence is ");
X					 for (i = 0; i < st[style].st_length; i++) 
X					   fprintf(stderr, "'%s', ", st[style].st_seq[i]);
X    	   	  	 	    	 fprintf(stderr, "\n  Spacing %.1f points\n", 
X    	   	  	 	    		    st[style].st_spacing);
X    	   	  	 	  }
X			   }
X			   c_token++;
X		    }
X		}
X		else if (almost_equals(c_token,"a$ll")) {
X			c_token++;
X			(void) putc('\n',stderr);
X			show_version();
X			fprintf(stderr,"functions are plotted with %s\n",
X				   st[(int)func_style].st_name);
X			fprintf(stderr,"data is plotted with %s\n",
X				   st[(int)data_style].st_name);
X			fprintf(stderr,"output is sent to %s\n",outstr);
X			fprintf(stderr,"terminal type is %s\n",term_tbl[term].name);
X			fprintf(stderr,"sampling rate is %d\n\n",samples);
X			if (log_x && log_y) 
X				fprintf(stderr,"logscaling both x and y axes\n");
X			else if (log_x)
X				fprintf(stderr,"logscaling x axis\n");
X			else if (log_y)
X				fprintf(stderr,"logscaling y axis\n");
X			else 
X				fprintf(stderr,"no logscaling\n");
X			fprintf(stderr,"x autoscaling is %s\n",(autoscale_x)? "ON" : "OFF");
X			fprintf(stderr,"y autoscaling is %s\n",(autoscale_y)? "ON" : "OFF");
X			fprintf(stderr,"zero is %g\n",zero);
X			fprintf(stderr,"xrange is [%g : %g]\n",xmin,xmax);
X			fprintf(stderr,"yrange is [%g : %g]\n",ymin,ymax);
X		    fprintf(stderr, "title is '%s'\n", title_string);
X		    fprintf(stderr, "x axis label is '%s'\n", xlabel_string);
X		    fprintf(stderr, "y axis label is '%s', spacing factor %d\n",
X				  ylabel_string, y_skip_factor);
X		    fprintf(stderr, "plot size is %g\" wide, %g\" high\n",
X				  plot_width, plot_height);
X			fprintf(stderr, "clipping is %s\n", clipping ? "ON" : "OFF");
X			fprintf(stderr, "xtics are %s\n", xtics ? "ON" : "OFF");
X			fprintf(stderr, "ytics are %s\n", ytics ? "ON" : "OFF");
X			view_variables();
X			view_functions();
X			fprintf(stderr, "\nAvailable plot styles are:\n");
X			for (style = 0; style < next_style; style++) {
X			    fprintf(stderr, "  %s\n", st[style].st_name);
X			}
X			fprintf(stderr, "For more info on style xxx type 'show style xxx'\n");
X			c_token++;
X		}
X		else
X			int_error("unknown show option (try 'help show')",c_token);
X	}
X	else if (almost_equals(c_token,"cl$ear")) { /* now does clear screen! */
X		if (!term_init) {
X			(*term_tbl[term].init)();
X			term_init = TRUE;
X		}
X		/* Below is a hack; no terminal but LATEX uses all these
X		 * arguments, and calling this here in LATEX hardly 'clears'
X		 * the screen.  (DFK 10/87)
X		 */
X		(*term_tbl[term].graphics)(plot_width, plot_height,
X							  &(term_tbl[term]),
X							  xlabel_string, ylabel_string, 
X							  y_skip_factor,
X							  title_string);
X		(*term_tbl[term].text)();
X		(void) fflush(outfile);
X		screen_ok = FALSE;
X		c_token++;
X	}
X	else if (almost_equals(c_token,"she$ll")) {
X		do_shell();
X		screen_ok = FALSE;
X		c_token++;
X	}
X	else if (almost_equals(c_token,"sa$ve")) {
X		if (almost_equals(++c_token,"f$unctions")) {
X			if (!isstring(++c_token))
X				int_error("expecting filename",c_token);
X			else {
X				quote_str(sv_file,c_token);
X				save_functions(fopen(sv_file,"w"));
X			}
X		}
X		else if (almost_equals(c_token,"v$ariables")) {
X			if (!isstring(++c_token))
X				int_error("expecting filename",c_token);
X			else {
X				quote_str(sv_file,c_token);
X				save_variables(fopen(sv_file,"w"));
X			}
X		}
X		else if (isstring(c_token)) {
X				quote_str(sv_file,c_token);
X				save_all(fopen(sv_file,"w"));
X		}
X		else {
X			int_error(
X		"filename or keyword 'functions' or 'variables' expected",c_token);
X		}
X		c_token++;
X	}
X	else if (almost_equals(c_token,"lo$ad")) {
X		if (!isstring(++c_token))
X			int_error("expecting filename",c_token);
X		else {
X			quote_str(sv_file,c_token);
X			load_file(fopen(sv_file,"r"));	
X		}
X	/* input_line[] and token[] now destroyed! */
X	}
X	else if (almost_equals(c_token,"ex$it") ||
X		almost_equals(c_token,"q$uit")) {
X		done(IO_SUCCESS);
X	}
X	else if (!equals(c_token,";")) {		/* null statement */
X		int_error("invalid command",c_token);
X	}
X}
X
X
Xload_range(a,b)
Xdouble *a,*b;
X{
Xstruct value t;
X
X	if (equals(c_token,"]"))
X		return;
X	if (END_OF_COMMAND) {
X	    int_error("starting range value or 'to' expected",c_token);
X	} else if (!equals(c_token,"to") && !equals(c_token,":"))  {
X		*a = real(const_express(&t));
X	}	
X	if (!equals(c_token,"to") && !equals(c_token,":")) 
X		int_error("Keyword 'to' or ':' expected",c_token);
X	c_token++; 
X	if (!equals(c_token,"]"))
X		*b = real(const_express(&t));
X}
X
X
Xplotrequest()
X{
X    autoscale_lx = autoscale_x;
X    autoscale_ly = autoscale_y;
X
X	dummy_var[0] = 'x';  /* default */
X	dummy_var[1] = '\0'; 
X	if (equals(c_token,"[")) {
X		c_token++;
X		if (isletter(c_token)) {
X			copy_str(dummy_var,c_token++);
X			if (equals(c_token,"="))
X				c_token++;
X			else
X				int_error("'=' expected",c_token);
X		}
X		load_range(&xmin,&xmax);
X		autoscale_lx = FALSE;
X		if (!equals(c_token,"]"))
X			int_error("']' expected",c_token);
X		c_token++;
X	}
X
X	if (equals(c_token,"[")) { /* set optional y ranges */
X		c_token++;
X		load_range(&ymin,&ymax);
X		autoscale_ly = FALSE;
X		if (!equals(c_token,"]"))
X			int_error("']' expected",c_token);
X		c_token++;
X	}
X
X	eval_plots();
X}
X
X/* Parse the definition of a style and add to table */
Xint add_style()
X{
X    register int i;
X    int style = -1;				/* the new style number */
X    struct value a;
X    register struct st_entry *stp;	/* quick access to new entry */
X    int null_definition = TRUE; /* watch out for missing definitions */
X
X	/* check if it's already in the table... */
X
X    style = -1;
X	for (i = 0; i < next_value; i++) {
X		if (equals(c_token,st[i].st_name))
X			style = i;
X	}
X    /* Not found - assign a new one */
X    if (style < 0)
X	 style = next_style;
X    /* Found - redefine it */
X    if (style <= FIXED_STYLES)
X	 int_error("cannot redefine this style", c_token);
X    if (style == MAX_STYLES)
X	 int_error("user defined style space full",NO_CARET);
X    else
X	 next_style++;
X
X    stp = &st[style];
X
X    /* Copy in the name of the style */
X    copy_str(stp->st_name,c_token);
X    stp->st_undef = TRUE;
X    c_token++;
X
X    /* Point type */
X    if(!isstring(c_token)) {
X	   *stp->st_point = '\0'; /* null point definition */
X    } else {
X	   quote_str(stp->st_point, c_token);
X	   c_token++;
X	   null_definition = FALSE;
X    }
X
X     /* Spacing */
X    if(END_OF_COMMAND) {
X	   stp->st_spacing = 0;
X	   stp->st_length = 0;
X    } else {
X	   /* read dot spacing */
X	   if (!isnumber(c_token)) {
X		  next_value--;
X		  int_error("expecting spacing (in points) for style", c_token);
X	   }
X	   convert(&a, c_token);
X	   stp->st_spacing = (int)magnitude(&a);
X	   if (stp->st_spacing < 0.1) {
X		  next_value--;
X		  int_error("unreasonable spacing value", c_token);
X	   }
X	   c_token++;
X
X	   /* build dot sequence */
X	   stp->st_length = 0;
X	   
X	   while(!(END_OF_COMMAND)) {
X		  if (!isstring(c_token))
X		    int_error("expecting a string defining a sequence style", c_token);
X		  quote_str(stp->st_seq[stp->st_length++], c_token);
X		  c_token++;
X		  if (stp->st_length >= MAX_STYLE_SEQ_LENGTH)
X		    int_error("style sequence too long", c_token);
X	   }
X	   null_definition = FALSE;
X
X	   if (stp->st_length == 0)
X		int_error("expecting dot sequence", c_token);
X    }
X
X    if (null_definition)
X	 int_error("expecting definition of style", c_token);
X
X    return(++c_token);
X}
X
X
Xlabelrequest()
X{
X    struct value a;
X    double x,y;			/* the point */
X    char pos[MAX_ID_LEN+1];	/* optional argument */
X    char text[MAX_ID_LEN+1];	/* text of the label */
X    double length = 0;		/* length of arrow */
X    int dx = 0, dy = 0;		/* slope of arrow */
X
X    /* x coordinate */
X    const_express(&a);
X    x = real(&a);
X
X    if (!equals(c_token, ","))
X	 int_error("comma expected", c_token);
X    c_token++;
X
X    /* y coordinate */
X    const_express(&a);
X    y = real(&a);
X
X    /* text */
X    if (isstring(c_token))
X	 quote_str(text, c_token++);
X    else
X	 int_error("expecting text of the label", c_token);
X
X    /* optional pos */
X    pos[0] = '\0';
X    if (!(END_OF_COMMAND)) {
X	   copy_str(pos, c_token++);
X	   
X	   /* optional length for optional arrow  */
X	   if (!(END_OF_COMMAND)) {
X		  const_express(&a);
X		  length = real(&a);
X
X		  if (!(END_OF_COMMAND)) {
X			 if (!equals(c_token, ","))
X			   int_error("comma expected", c_token);
X			 c_token++;
X		  
X			 const_express(&a);
X			 dx = (int) real(&a);
X
X			 if (!equals(c_token, ","))
X			   int_error("comma expected", c_token);
X			 c_token++;
X
X			 const_express(&a);
X			 dy = (int) real(&a);
X		  }
X	   }
X    }
X
X    do_label(x,y, text, pos, length, dx, dy);
X}
X
Xkeyrequest()
X{
X    struct value a;
X    double x,y;			/* the point */
X    int styles[MAX_KEYS+1];	/* the style for each plot */
X    char *text[MAX_KEYS+1];	/* text of each key entry */
X    int style;
X    int entry = 0;
X
X    /* x coordinate */
X    const_express(&a);
X    x = real(&a);
X
X    if (!equals(c_token, ","))
X	 int_error("comma expected", c_token);
X    c_token++;
X
X    /* y coordinate */
X    const_express(&a);
X    y = real(&a);
X
X    do {					/* scan the entries in the key */
X	   /* text */
X	   if (isstring(c_token)) {
X		  text[entry] = (char *) malloc(MAX_ID_LEN);
X		  quote_str(text[entry], c_token++);
X	   } else
X		int_error("expecting text of the key entry", c_token);
X	   
X	   if (almost_equals(c_token, "w$ith"))
X		c_token++;
X	   else
X		int_error("expecting 'with' style for key entry", c_token);
X
X	   for (style = 0; style < next_style; style++)
X		if (equals(c_token, st[style].st_name))
X		  break;
X	   if (style == next_style)
X		int_error("unknown plot style; type 'show style'", 
X				c_token);
X	   else
X		styles[entry] = style;
X	   c_token++;
X
X	   if (!END_OF_COMMAND)
X		if (!equals(c_token, ","))
X		  int_error("expecting ',' between key entries", c_token);
X		else
X		  c_token++;
X
X	   entry++;
X	   if (entry > MAX_KEYS)
X		int_error("too many lines in the key", c_token);
X    } while (!END_OF_COMMAND);
X
X    text[entry] = NULL;		/* acts as terminator */
X
X    do_key (x,y, styles, text);
X
X    for (entry--; entry >= 0; entry--)
X	 free(text[entry]);
X
X}
X
X
Xdefine()
X{
Xregister int value,start_token;  /* start_token is the 1st token in the	*/
X								/* function definition.			*/
X
X	if (equals(c_token+1,"(")) {
X		/* function ! */
X		start_token = c_token;
X		copy_str(dummy_var, c_token + 2);
X		c_token += 5; /* skip (, dummy, ) and = */
X		value = c_function = user_defined(start_token);
X		build_at(&(udft[value].at));
X				/* define User Defined Function (parse.c)*/
X		capture(udft[value].definition,start_token,c_token-1);
X	}
X	else {
X		/* variable ! */
X		c_token +=2;
X		(void) const_express(&vt[value = add_value(c_token - 2) ].vt_value);
X		vt[value].vt_undef = FALSE;
X	}
X}
X
X
X#define iscomment(c) (c == '!' || c == '#')
X
Xget_data(plot_num)
Xint plot_num;
X{
Xstatic char data_file[MAX_ID_LEN+1], line[MAX_LINE_LEN+1];
Xregister int i, l_num;
Xregister FILE *fp;
Xfloat x, y;
X
X	quote_str(data_file, c_token);
X	plot[plot_num].plot_type = DATA;
X	if (!(fp = fopen(data_file, "r")))
X		os_error("can't open data file", c_token);
X
X	l_num = 0;
X
X	i = 0;
X	while (fgets(line, MAX_LINE_LEN, fp)) {
X		l_num++;
X		if (iscomment(line[0]) || ! line[1])	/* line[0] will be '\n' */
X			continue;		/* ignore comments  and blank lines */
X		if (i > samples) {
X		    fprintf(stderr, 
X				  "Too many data points (limit is %d) in file '%s'\n",
X				  samples, data_file);
X		    fprintf(stderr, " To change limit, use 'set samples <limit>'\n");
X		    break;
X		}
X		switch (sscanf(line, "%f %f", &x, &y)) {
X			case 1:			/* only one number on the line */
X				y = x;		/* assign that number to y */
X				x = i;		/* and make the index into x */
X			/* no break; !!! */
X			case 2:
X				if (   (autoscale_lx || (x >= xmin && x <= xmax))
X				    && (autoscale_ly || (y >= ymin && y <= ymax))) {
X					if (log_x) {
X						if (x <= 0.0)
X							break;
X						plot[plot_num].points[i].x = log10(x);
X					} else
X						plot[plot_num].points[i].x = x;
X					if (log_y) {
X						if (y <= 0.0)
X							break;
X						plot[plot_num].points[i].y = log10(y);
X					} else
X						plot[plot_num].points[i].y = y;
X					plot[plot_num].points[i].undefined = FALSE;
X					if (autoscale_lx) {
X						if (x < xmin) xmin = x;
X						if (x > xmax) xmax = x;
X					}
X					if (autoscale_ly) {
X						if (y < ymin) ymin = y;
X						if (y > ymax) ymax = y;
X					}
X					i++;
X				}
X				break;
X			default:
X				(void) sprintf(line, "bad data on line %d", l_num);
X				int_error(line,c_token);
X		}
X	}
X	plot[plot_num].count = i;
X
X     fclose(fp);			/* DFK 6/8/87 Bugfix: never closed file! */
X}
X
X/* This parses the plot command after any range specifications. 
X * To support autoscaling on the x axis, we want any data files to 
X * define the x range, then to plot any functions using that range. 
X * We thus parse the input twice, once to pick up the data files, 
X * and again to pick up the functions. Definitions are processed 
X * twice, but that won't hurt.
X */
Xeval_plots()
X{
Xregister int i, plot_num, start_token, mysamples;
Xregister int begin_token;
Xregister double x_min, x_max, y_min, y_max, x;
Xregister double xdiff, temp;
Xstruct value a;
Xint style;
XBOOLEAN some_data_files = FALSE;
X
X	/* don't sample higher than output device can handle! */
X	mysamples = (samples <= term_tbl[term].xmax) ?samples :term_tbl[term].xmax;
X
X	if (autoscale_ly) {
X		ymin = HUGE;
X		ymax = -HUGE;
X	} else if (log_y && (ymin <= 0.0 || ymax <= 0.0))
X			int_error("y range must be greater than 0 for log scale!",
X				NO_CARET);
X
X	c_function = MAX_UDFS;		/* last udft[] entry used for plots */
X
X	plot_num = 0;
X
X     begin_token = c_token;
X
X/*** First Pass: Read through data files ***/
X/* This pass serves to set the xrange and to parse the command, as well 
X * as filling in every thing except the function data. That is done after
X * the xrange is defined.
X */
X	while (TRUE) {
X		if (END_OF_COMMAND)
X			int_error("function to plot expected",c_token);
X		if (plot_num == MAX_PLOTS || plot[plot_num].points == NULL)
X			int_error("maximum number of plots exceeded",NO_CARET);
X
X		start_token = c_token;
X
X		if (is_definition(c_token)) {
X			define();
X		} else {
X			if (isstring(c_token)) {			/* data file to plot */
X				if (!some_data_files && autoscale_lx) {
X				    xmin = HUGE;
X				    xmax = -HUGE;
X				}
X				some_data_files = TRUE;
X
X				plot[plot_num].plot_type = DATA;
X				plot[plot_num].plot_style = (int)data_style;
X				get_data(plot_num);
X				c_token++;
X			} 
X			else {							/* function to plot */
X				plot[plot_num].plot_type = FUNC;
X				plot[plot_num].plot_style = (int)func_style;
X				build_at(&udft[MAX_UDFS].at);
X				/* ignore it for now */
X			}
X			capture(plot[plot_num].title,start_token,c_token-1);
X			if (almost_equals(c_token,"w$ith")) {
X				c_token++;
X				for (style = 0; style < next_style; style++)
X				  if (equals(c_token, st[style].st_name))
X				    break;
X				if (style == next_style)
X				  int_error("unknown plot style; type 'show style'", 
X						  c_token);
X				else
X				  plot[plot_num].plot_style = style;
X				c_token++;
X			}
X			plot_num++;
X		}
X
X		if (equals(c_token,",")) 
X			c_token++;
X		else  
X			break;
X	}
X
X/*** Second Pass: Evaluate the functions ***/
X/* Everything is defined now, except the function data. We expect
X * no syntax errors, etc, since the above parsed it all. This makes 
X * the code below simpler. If autoscale_ly, the yrange may still change.
X */
X     if (xmin == xmax)
X	  if (autoscale_lx) {
X		 fprintf(stderr,
X			    "Warning: empty x range [%g:%g], adjusting to [%g:%g]\n",
X			    xmin,xmax, xmin*0.9, xmax*1.1);
X		 xmin = xmin * 0.9;	/* expand range by 10% in either direction */
X		 xmax = xmax * 1.1;
X	  } else {
X		 int_error("x range is empty", c_token);
X	  }
X
X    if (log_x) {
X	   if (xmin < 0.0 || xmax < 0.0)
X		int_error("x range must be greater than 0 for log scale!",NO_CARET);
X	   x_min = log10(xmin);
X	   x_max = log10(xmax);
X    } else {
X	   x_min = xmin;
X	   x_max = xmax;
X    }
X    
X    xdiff = (x_max - x_min) / mysamples;
X    
X    c_function = MAX_UDFS;		/* last udft[] entry used for plots */
X    plot_num = 0;
X    c_token = begin_token;	/* start over */
X
X    /* Read through data files */
X	while (TRUE) {
X		if (is_definition(c_token)) {
X			define();
X		} else {
X			if (isstring(c_token)) {			/* data file to plot */
X			    /* ignore this now */
X				c_token++;
X			} 
X			else {							/* function to plot */
X				build_at(&udft[MAX_UDFS].at);
X    
X				for (i = 0; i <= mysamples; i++) {
X				    if (i == samples+1)
X					 int_error("number of points exceeded samples",
X							 NO_CARET);
X				    x = x_min + i*xdiff;
X				    if (log_x)
X					 x = pow(10.0,x);
X				    (void) complex(&udft[MAX_UDFS].dummy_value, x, 0.0);
X				    
X				    evaluate_at(&udft[MAX_UDFS].at,&a);
X				    
X				    if (plot[plot_num].points[i].undefined =
X					   undefined || (fabs(imag(&a)) > zero))
X					 continue;
X				    
X				    temp = real(&a);
X				    
X				    if (log_y && temp <= 0.0) {
X					   plot[plot_num].points[i].undefined = TRUE;
X					   continue;
X				    }
X				    if (autoscale_ly) {
X					   if (temp < ymin) ymin = temp;
X					   if (temp > ymax) ymax = temp;
X				    } else if (temp < ymin || temp > ymax) {
X					   plot[plot_num].points[i].undefined = TRUE;
X					   continue;
X				    }
X				    
X				    plot[plot_num].points[i].y = 
X					 log_y ? log10(temp) : temp;
X				}
X				plot[plot_num].count = i; /* mysamples + 1 */
X			 }
X			
X			/* style was handled above */
X			if (almost_equals(c_token,"w$ith")) {
X			    c_token++;
X			    c_token++;
X			}
X			plot_num++;
X		 }
X		
X		if (equals(c_token,",")) 
X		  c_token++;
X		else  
X		  break;
X	 }
X
X    if (ymin == ymax)
X	 if (autoscale_ly) {
X		fprintf(stderr,
X			   "Warning: empty y range [%g:%g], adjusting to [%g:%g]\n",
X			   ymin,ymax, ymin*0.9, ymax*1.1);
X		ymin = ymin * 0.9;	/* expand range by 10% in either direction */
X		ymax = ymax * 1.1;
X	 } else {
X		int_error("y range is empty", c_token);
X	 }
X
X/* Now we finally know the real ymin and ymax */
X	if (log_y) {
X		y_min = log10(ymin);
X		y_max = log10(ymax);
X	} else {
X		y_min = ymin;
X		y_max = ymax;
X	}
X	do_plot(plot,plot_num,x_min,x_max,y_min,y_max);
X}
X
X
X
Xdone(status)
Xint status;
X{
X	if (term)
X		(*term_tbl[term].reset)();
X	exit(status);
X}
X
X#ifdef vms
Xdo_shell()
X{
X	if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
X		os_error("spawn error");
X	}
X}
X
X#else /* vms */
X
X#ifdef MSDOS
X
Xdo_shell()
X{
Xregister char *comspec;
X	if (!(comspec = getenv("COMSPEC")))
X		comspec = "\command.com";
X	if (spawnl(P_WAIT,comspec,NULL))
X		os_error("unable to spawn shell");
X}
X
X#else /* MSDOS */
X
X#ifdef VFORK
X
Xdo_shell()
X{
Xregister char *shell;
Xregister int p;
Xstatic int execstat;
X	if (!(shell = getenv("SHELL")))
X		shell = SHELL;
X	if ((p = vfork()) == 0) {
X		execstat = execl(shell,shell,NULL);
X		_exit(1);
X	} else if (p == -1)
X		os_error("vfork failed",c_token);
X	else
X		while (wait(NULL) != p)
X			;
X	if (execstat == -1)
X		os_error("shell exec failed",c_token);
X	(void) putc('\n',stderr);
X}
X#else /* VFORK */
X
X#define EXEC "exec "
Xdo_shell()
X{
Xstatic char exec[100] = EXEC;
Xregister char *shell;
X	if (!(shell = getenv("SHELL")))
X		shell = SHELL;
X
X	if (system(strcpy(&exec[sizeof(EXEC)-1],shell)))
X		os_error("system() failed",NO_CARET);
X
X	(void) putc('\n',stderr);
X}
X#endif /* VFORK */
X#endif /* MSDOS */
X#endif /* vms */
SHAR_EOF
fi # end of overwriting check
if test -f 'eval.c'
then
	echo shar: will not over-write existing file "'eval.c'"
else
sed 's/^X//' << \SHAR_EOF > 'eval.c'
X/*
X *
X *    G N U P L O T  --  eval.c
X *
X *  Copyright (C) 1986 Colin Kelley, Thomas Williams
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X
X#include <stdio.h>
X#include "plot.h"
X
Xextern int c_token,next_value,next_function;
Xextern struct udft_entry udft[];
Xextern struct ft_entry ft[];
Xextern struct vt_entry vt[];
Xextern struct at_type *curr_at;
Xextern struct lexical_unit token[];
X
Xstruct value *integer();
X
X
X
Xint add_value(t_num)
Xint t_num;
X{
Xregister int i;
X
X	/* check if it's already in the table... */
X
X	for (i = 0; i < next_value; i++) {
X		if (equals(t_num,vt[i].vt_name))
X			return(i);
X	}
X	if (next_value == MAX_VALUES)
X		int_error("user defined constant space full",NO_CARET);
X	copy_str(vt[next_value].vt_name,t_num);
X	vt[next_value].vt_value.type = INT;		/* not necessary, but safe! */
X	vt[next_value].vt_undef = TRUE;
X	return(next_value++);
X}
X
X
Xadd_action(sf_index,arg)
Xenum operators sf_index;
Xstruct value *arg;
X
X /* argument to pass to standard function indexed by sf_index */
X{
X
X	if ( curr_at->count >= MAX_AT_LEN ) 
X		int_error("action table overflow",NO_CARET);
X	curr_at->actions[curr_at->count].index = ((int)sf_index);
X	if (arg != (struct value *)0)
X		curr_at->actions[curr_at->count].arg = *arg;
X	curr_at->count++;
X}
X
X
Xint standard(t_num)  /* return standard function index or 0 */
X{
Xregister int i;
X	for (i = (int)SF_START; ft[i].ft_name != NULL; i++) {
X		if (equals(t_num,ft[i].ft_name))
X			return(i);
X	}
X	return(0);
X}
X
X
X
Xint user_defined(t_num)  /* find or add function and return index */
Xint t_num; /* index to token[] */
X{
Xregister int i;
X	for (i = 0; i < next_function; i++) {
X		if (equals(t_num,udft[i].udft_name))
X			return(i);
X	}
X	if (next_function == MAX_UDFS)
X		int_error("user defined function space full",t_num);
X	copy_str(udft[next_function].udft_name,t_num);
X	udft[next_function].definition[0] = '\0';
X	udft[next_function].at.count = 0;
X	(void) integer(&udft[next_function].dummy_value, 0);
X	return(next_function++);
X}
X
X 
X
Xexecute_at(at_ptr)
Xstruct at_type *at_ptr;
X{
Xregister int i;
X	for (i = 0; i < at_ptr->count; i++) {
X		(*ft[at_ptr->actions[i].index].funct)(&(at_ptr->actions[i].arg));
X	}
X}
X
X/*
X
X 'ft' is a table containing C functions within this program. 
X
X An 'action_table' contains pointers to these functions and arguments to be
X passed to them. 
X
X at_ptr is a pointer to the action table which must be executed (evaluated)
X
X so the iterated line exectues the function indexed by the at_ptr and 
X passes the argument which is pointed to by the arg_ptr 
X
X*/
SHAR_EOF
fi # end of overwriting check
if test -f 'graphics.c'
then
	echo shar: will not over-write existing file "'graphics.c'"
else
sed 's/^X//' << \SHAR_EOF > 'graphics.c'
X/*
X *
X *    G N U P L O T  --  graphics.c
X *
X *  Copyright (C) 1986 Thomas Williams, Colin Kelley
X *
X *  You may use this code as you wish if credit is given and this message
X *  is retained.
X *
X *  Please e-mail any useful additions to vu-vlsi!plot so they may be
X *  included in later releases.
X *
X *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
X */
X/*
X * Modifications for LaTeX and other support by David Kotz, 1988.
X * Department of Computer Science, Duke University, Durham, NC 27706.
X * Mail to dfk@cs.duke.edu.
X */
X
X#include <stdio.h>
X#include <math.h>
X#include "plot.h"
X
Xchar *strcpy(),*strncpy(),*strcat();
X
Xextern FILE *outfile;
Xextern BOOLEAN log_x, log_y;
Xextern int term;
X
Xextern BOOLEAN printer;		/* DFK 6/8/87 */
X
Xextern BOOLEAN screen_ok;
Xextern BOOLEAN term_init;
X
Xextern struct termentry term_tbl[];
X
Xextern int put_label;
X
Xextern char title_string[];
Xextern char xlabel_string[];
Xextern char ylabel_string[];
Xextern char xformat[];
Xextern char yformat[];
Xextern int y_skip_factor;
Xextern double plot_width;
Xextern double plot_height;
Xextern struct st_entry st[];
Xextern BOOLEAN xtics;
Xextern BOOLEAN ytics;
X
X#ifndef max		/* Lattice C has max() in math.h, but shouldn't! */
X#define max(a,b) ((a > b) ? a : b)
X#endif
X
X#define map_x(x) (int)((x-xmin)*xscale) /* maps floating point x to screen */ 
X#define map_y(y) (int)((y-ymin)*yscale)	/* same for y */
X
X/* (DFK) Watch for cancellation error near zero on axes labels */
X#define SIGNIF (0.01)		/* less than one hundredth of a tic mark */
X#define CheckZero(x,tic) (fabs(x) < ((tic) * SIGNIF) ? 0.0 : (x))
X
X/* Remember these from the last do_plot  */
Xstatic double last_xmin, last_ymin;
Xstatic double last_xscale, last_yscale;
X
Xdouble raise(x,y)
Xdouble x;
Xint y;
X{
Xregister int i;
Xdouble val;
X
X	val = 1.0;
X	for (i=0; i < abs(y); i++)
X		val *= x;
X	if (y < 0 ) return (1.0/val);
X	return(val);
X}
X
X
Xdouble make_tics(tmin,tmax,logscale)
Xdouble tmin,tmax;
XBOOLEAN logscale;
X{
Xdouble xr,xnorm,tics,tic,l10;
X
X	xr = fabs(tmin-tmax);
X	
X	l10 = log10(xr);
X	if (logscale) {
X		tic = raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
X		if (tic < 1.0)
X			tic = 1.0;
X	} else {
X		xnorm = pow(10.0,l10-(double)((l10 >= 0.0 ) ? (int)l10 : ((int)l10-1)));
X		if (xnorm <= 2)
X			tics = 0.2;
X		else if (xnorm <= 5)
X			tics = 0.5;
X		else tics = 1.0;	
X		tic = tics * raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
X	}
X	return(tic);
X}
X
Xchar *idx(a,b)
Xregister char *a,b;
X{
X	do {
X		if (*a == b)
X			return(a);
X	} while (*a++);
X	return(0);
X}
X
X 
Xnum2str(num,str)
Xdouble num;
Xchar str[];
X{
Xchar temp[80];
Xchar *a,*b;
X
X 	if (fabs(num) > 9999.0 || fabs(num) < 0.001 && fabs(num) != 0.0) 
X		(void) sprintf(temp,"%-.3e",num);	
X	else
X		(void) sprintf(temp,"%-.3g",num);
X	if (b = idx(temp,'e')) {
X		a = b-1;     /* b points to 'e'.  a points before 'e' */
X		while ( *a == '0') /* trailing zeros */
X			a--;	
X		if ( *a == '.') 
X			a--;
X		(void) strncpy(str,temp,(int)(a-temp)+1);
X		str[(int)(a-temp)+1] = '\0';
X		a = b+1;	/* point to 1 after 'e' */
X		if ( *a == '-') 
X			(void) strcat(str,"e-");
X		else	
X			(void) strcat(str,"e");
X		a++; /* advance a past '+' or '-' */
X		while ( *a == '0' && *(a+1) != '\0') /* leading blanks */
X			a++;
X		(void) strcat(str,a); /* copy rest of string */
X	}
X	else
X		(void) strcpy(str,temp);	
X}
X
X
Xdo_plot(plots, p_count, xmin, xmax, ymin, ymax)
Xstruct curve_points plots[MAX_PLOTS];
Xint p_count;			/* count of plots to do */
Xdouble xmin, xmax;
Xdouble ymin, ymax;
X{
Xregister int curve, i, x, xaxis_y, yaxis_x,dp_count;
Xregister BOOLEAN prev_undef;
Xregister enum PLOT_TYPES p_type;
Xregister double xscale, yscale;
Xregister double ytic, xtic, least, most, ticplace;
Xregister struct termentry *t = &term_tbl[term];
Xregister int mms,mts;
Xstatic char xns[20],xms[20],yns[20],yms[20],xts[20],yts[20];
Xstatic char label[80];
Xchar *special;
Xint lines;
Xstruct st_entry *stp;
Xint title_line = 0;
X
X	if (ymin == HUGE || ymax == -HUGE)
X		int_error("all points undefined!", NO_CARET);
X
X	ytic = make_tics(ymin,ymax,log_y);
X	xtic = make_tics(xmin,xmax,log_x);
X	dp_count = 0;
X	
X	if (ymin < ymax ) {
X		ymin = ytic * floor(ymin/ytic);	
X		ymax = ytic * ceil(ymax/ytic);
X	}
X	else {
X		ymin = ytic * ceil(ymin/ytic);
X		ymax = ytic * floor(ymax/ytic);
X	}
X
X	if (xmin == xmax)
X		int_error("xmin should not equal xmax!",NO_CARET);
X	if (ymin == ymax)
X		int_error("ymin should not equal ymax!",NO_CARET);
X	
X	if (!term_init) {
X		(*t->init)();
X		term_init = TRUE;
X	}
X	screen_ok = FALSE;
X     if (!printer) {			/* DFK 6/8/87 */
X	    (*t->graphics)(plot_width, plot_height, t,
X				    xlabel_string, ylabel_string, y_skip_factor,
X				    title_string);
X	} else {
X	    printer = FALSE;
X	}
X
X     /* NOW we can figure the scale from the terminal's resolution */
X	yscale = (t->ymax - 2)/(ymax - ymin);
X	xscale = (t->xmax - 2)/(xmax - xmin);
X	
X     /* And remember them all for later use in do_label */
X    last_xmin = xmin;
X    last_ymin = ymin;
X    last_xscale = xscale;
X    last_yscale = yscale;
X
X	/* draw plot border */
X	(*t->linetype)(-2); /* border linetype */
X	(*t->move)(0,0);	
X	(*t->vector)(t->xmax-1,0);	
X	(*t->vector)(t->xmax-1,t->ymax-1);	
X	(*t->vector)(0,t->ymax-1);	
X	(*t->vector)(0,0);
X
X     if (ytics) {
X	    least = (ymin < ymax) ? ymin : ymax;
X	    most = (ymin < ymax) ? ymax : ymin;
X
X	    (*t->ytick_text)(map_y(least), CheckZero(least,ytic), yformat);
X	    for (ticplace = ytic + least; ticplace < most ; ticplace += ytic) { 
X		   (*t->move)(0,map_y(ticplace));
X		   (*t->vector)(t->h_tic,map_y(ticplace));
X		   (*t->move)(t->xmax-1,map_y(ticplace));
X		   (*t->vector)(t->xmax-1-t->h_tic,map_y(ticplace));
X		   (*t->ytick_text)(map_y(ticplace), CheckZero(ticplace,ytic), yformat);
X	    }
X	    (*t->ytick_text)(map_y(most), CheckZero(most,ytic), yformat);
X	}
X
X     if (xtics) {
X	    if (xmin < xmax ) {
X		   least = xtic * floor(xmin/xtic);	
X		   most = xtic * ceil(xmax/xtic);
X		   if (least >= xmin) 
X			(*t->xtick_text)(map_x(least), CheckZero(least,xtic), xformat);
X		   if (most <= xmax)
X			(*t->xtick_text)(map_x(most), CheckZero(most,xtic), xformat);
X	    }
X	    else {
X		   least = xtic * ceil(xmin/xtic);
X		   most = xtic * floor(xmax/xtic);
X		   if (least <= xmin) 
X			(*t->xtick_text)(map_x(least), CheckZero(least,xtic), xformat);
X		   if (most >= xmax)
X			(*t->xtick_text)(map_x(most), CheckZero(most,xtic), xformat);
X	    }
X	    
X	    for (ticplace = xtic + least; ticplace < most ; ticplace += xtic) { 
X		   (*t->move)(map_x(ticplace),0);
X		   (*t->vector)(map_x(ticplace),t->v_tic);
X		   (*t->move)(map_x(ticplace),t->ymax-1);
X		   (*t->vector)(map_x(ticplace),t->ymax-1-t->v_tic);
X		   (*t->xtick_text)(map_x(ticplace), CheckZero(ticplace,xtic), xformat);
X	    }
X	}
X
X	if (log_x) {
X		num2str(pow(10.0,xmin),xns);
X		num2str(pow(10.0,xmax),xms);
X		num2str(pow(10.0,xtic),xts);
X	}
X	else {
X		num2str(xmin,xns);
X		num2str(xmax,xms);
X		num2str(xtic,xts);
X	}
X	if (log_y) {
X		num2str(pow(10.0,ymin),yns);
X		num2str(pow(10.0,ymax),yms);
X		num2str(pow(10.0,ytic),yts);
X	} else {
X		num2str(ymin,yns);
X		num2str(ymax,yms);
X		num2str(ytic,yts);
X	}
X	mms = max(strlen(xms),strlen(yms));
X	mts = max(strlen(xts),strlen(yts));
X
X	if (put_label) {
X	  (void) sprintf(label,"%s < y < %-*s  inc = %-*s",yns,mms,yms,mts,yts);
X	  (*t->lrput_text)(0, label);
X	  (void) sprintf(label,"%s < x < %-*s  inc = %-*s",xns,mms,xms,mts,xts);
X	  (*t->lrput_text)(1, label);
X
X	  if (*title_string != '\0') {
X		 (*t->ulput_text)(0, title_string);
X		 title_line = 1;
X	  } else {
X		 title_line = 0;
X	  }
X	}
X
X
X/* DRAW AXES */
X	(*t->linetype)(-1);	/* axis line type */
X	xaxis_y = map_y(0.0);
X	yaxis_x = map_x(0.0); 
X
X	if (xaxis_y < 0)
X		xaxis_y = 0;				/* save for impulse plotting */
X	else if (xaxis_y >= t->ymax)
X		xaxis_y = t->ymax - 1;
X	else if (!log_y) {
X		(*t->move)(0,xaxis_y);
X		(*t->vector)((t->xmax-1),xaxis_y);
X	}
X
X	if (!log_x && yaxis_x >= 0 && yaxis_x < t->xmax) {
X		(*t->move)(yaxis_x,0);
X		(*t->vector)(yaxis_x,(t->ymax-1));
X	}
X
X/* DRAW CURVES */
X	for (curve = 0; curve < p_count; curve++) {
X		(*t->linetype)(curve);
X		if (put_label)
X			(*t->ulput_text)(curve + title_line, plots[curve].title);
X		(*t->linetype)(curve);
X
X		lines = TRUE;
X		special = NULL;
X
X		p_type = plots[curve].plot_type;
X		switch(plots[curve].plot_style) {
X			case IMPULSES:
X		    	 	(*t->linetype)(-1);	/* get straight lines */
X				for (i = 0; i < plots[curve].count; i++) {
X					if (!plots[curve].points[i].undefined) {
X						if (p_type == DATA)
X							x = map_x(plots[curve].points[i].x);
X						else
X							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
X						(*t->move)(x,xaxis_y);
X						(*t->vector)(x,map_y(plots[curve].points[i].y));
X					}
X				}
X				break;
X			case LINES:
X				prev_undef = TRUE;
X				for (i = 0; i < plots[curve].count; i++) {
X					if (!plots[curve].points[i].undefined) {
X						if (p_type == DATA)
X							x = map_x(plots[curve].points[i].x);
X						else
X							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
X						if (prev_undef)
X							(*t->move)(x,
X							map_y(plots[curve].points[i].y));
X						(*t->vector)(x,
X							map_y(plots[curve].points[i].y));
X					}
X					prev_undef = plots[curve].points[i].undefined;
X				}
X				break;
X			case POINTS:
X				for (i = 0; i < plots[curve].count; i++) {
X					if (!plots[curve].points[i].undefined) {
X						if (p_type == DATA)
X							x = map_x(plots[curve].points[i].x);
X						else
X							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
X						(*t->point)(x,map_y(plots[curve].points[i].y),dp_count, NULL);
X					}
X				}
X				dp_count++;
X				break;
X			case DOTS:
X				for (i = 0; i < plots[curve].count; i++) {
X					if (!plots[curve].points[i].undefined) {
X						if (p_type == DATA)
X							x = map_x(plots[curve].points[i].x);
X						else
X							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
X						(*t->point)(x,map_y(plots[curve].points[i].y),-1, NULL);
X					}
X				}
X				break;
X    	   	     default:		/* user-defined styles */
X				stp = &st[plots[curve].plot_style];
X				(*t->plotstyle)(stp);
X				lines = stp->st_length > 0;
X				special = stp->st_point;
X				/* FALL THROUGH */
X			case LINESPOINTS:		/* DFK 6/26/87 */
X				prev_undef = TRUE;
X				for (i = 0; i < plots[curve].count; i++) {
X					if (!plots[curve].points[i].undefined) {
X						if (p_type == DATA)
X							x = map_x(plots[curve].points[i].x);
X						else
X							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
X						if (prev_undef)
X							(*t->move)(x,
X							map_y(plots[curve].points[i].y));
X						if (lines)
X						  (*t->vector)(x, 
X									map_y(plots[curve].points[i].y));
X						if (special != NULL)
X						  if (*special != '\0')
X						    /* plot user-specified point */
X						    (*t->point)(x,
X									 map_y(plots[curve].points[i].y),
X									 0, special);
X						  else
X						    ; /* plot no point at all */
X						else	/* plot the normal type of point */
X						  (*t->point)(x,map_y(plots[curve].points[i].y),
X								    dp_count, NULL);
X					}
X					prev_undef = plots[curve].points[i].undefined;
X				}
X				if (special == NULL)
X				  dp_count++;
X				break;
X
X		}
X	}
X	(*t->text)();
X	(void) fflush(outfile);
X}
X
X/* Put an arbitrary label at some point on the graph (DFK 1/28/88) */
X/* Currently supported only by LaTeX terminal type */
Xdo_label(x, y, string, pos, length, dx, dy)
X	double x,y;
X	char *string;			/* the text */
X	char *pos;			/* optional [pos] in \makebox */
X	double length;			/* optional length of the arrow */
X	int dx, dy;			/* optional arrow slope */
X{
X    double xmin = last_xmin;
X    double ymin = last_ymin;
X    double xscale = last_xscale;
X    double yscale = last_yscale;
X    struct termentry *t = &term_tbl[term];
X
X    if (strcmp(pos,"b")==0 || strcmp(pos,"t")==0 || (dx == 0 && dy != 0)) {
X	   /* vertical line, interpret length as vertical extent */
X	   (*t->xyput_text)(map_x(x), map_y(y), string, pos, 
X					map_y(length) - map_y(0), dx, dy);
X    } else {
X	   /* non-vertical line, use length as horizontal extent */
X	   (*t->xyput_text)(map_x(x), map_y(y), string, pos, 
X					map_x(length) - map_x(0), dx, dy);
X    }
X}
X
X/* Plot a key somewhere on the last plot. */
Xdo_key (x,y, style, text)
X	double x,y;			/* location of key */
X	int style[];			/* which style does it use? */
X	char *text[];			/* description for key */
X{
X    double xmin = last_xmin;
X    double ymin = last_ymin;
X    double xscale = last_xscale;
X    double yscale = last_yscale;
X
X    /* Hack: call LATEX routine directly. Yuck. */
X    LATEX_key((unsigned long) map_x(x), (unsigned long) map_y(y), style, text);
X}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
Department of Computer Science, Duke University, Durham, NC 27706
ARPA:	dfk@cs.duke.edu
CSNET:	dfk@duke        
UUCP:	decvax!duke!dfk