[comp.text] GnuTeX version 1.3 source part 3

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 -f 'ideas'
then
	echo shar: will not over-write existing file "'ideas'"
else
sed 's/^X//' << \SHAR_EOF > 'ideas'
XUser-specify tic marks with 
X	   [xy]tics start incr
Xor
X	   [xy]tics t1,t2,...,tn
X(n may be 1 to, say, 20)
X
X----
Xallow tic marks to be labelled with non-numerics
X
X----
Xallow input data (and labels) to be an enumeration type (eg. {Male,Female})
X
X----
Xprovide a FIG output mode
X
X----
Xuse EEPIC to draw plot lines
X
X------
Xcan I get a frame around the key?
X
X-----
X
Xconsider adding a "width" parameter to the impulses style to get bar graphs.
X-rick
X
XFrom dfk Fri Dec 16 11:00:34 1988
XReceived: by romeo.cs.duke.edu (5.59/DUKE/08-19-88)
X	id AA19450; Fri, 16 Dec 88 11:00:24 EST
XDate: Fri, 16 Dec 88 11:00:24 EST
XFrom: David F. Kotz <dfk>
XMessage-Id: <8812161600.AA19450@romeo.cs.duke.edu>
XTo: texhax@score.stanford.edu
XCc: dfk
XSubject: problem with picture mode
XStatus: R
X
XI have a problem with \makebox in LaTeX picture mode. The LaTeX book
Xsays that its reference point is the lower-left corner. I figure that
Xif I use dimensions (0,0) and the default "pos" (which is horiz and
Xvert centered), the object in my box would be centered on the point.
XThe following example does not center the second and third circles
Xcorrectly:
X
X\setlength{\unitlength}{10pt}
X\begin{picture}(50,50)
X\put(15,20){\line(1,0){10}}
X\put(20,15){\line(0,1){10}}
X\put(20,20){\circle{5}}                 % Centers fine
X\put(20,20){\makebox(0,0){\circle{3}}}  % Too high
X\put(20,20){\makebox(0,0){\circle{.3}}} % Too far left
X\end{picture}
X
XThis is LATEX VERSION 2.09 <26 Apr 1988>
X
XDavid Kotz
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 'internal.c'
then
	echo shar: will not over-write existing file "'internal.c'"
else
sed 's/^X//' << \SHAR_EOF > 'internal.c'
X/*
X *
X *    G N U P L O T  --  internal.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 <math.h>
X#include <stdio.h>
X#include "plot.h"
X
Xextern BOOLEAN undefined;
Xextern struct vt_entry vt[MAX_VALUES];
Xextern struct udft_entry udft[MAX_UDFS];
X
Xchar *strcpy();
X
Xstruct value *pop(), *complex(), *integer();
Xdouble magnitude(), angle(), real();
X
Xstruct value stack[STACK_DEPTH];
X
Xint s_p = -1;   /* stack pointer */
X
X
X/*
X * System V and MSC 4.0 call this when they wants to print an error message.
X * Don't!
X */
Xmatherr()
X{
X	return (undefined = TRUE);		/* don't print error message */
X}
X
X
Xreset_stack()
X{
X	s_p = -1;
X}
X
X
Xcheck_stack()	/* make sure stack's empty */
X{
X	if (s_p != -1)
X		fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
X}
X
X
Xstruct value *pop(x)
Xstruct value *x;
X{
X	if (s_p  < 0 )
X		int_error("stack underflow",NO_CARET);
X	*x = stack[s_p--];
X	return(x);
X}
X
X#define ERR_VAR "undefined variable: "
X
Xf_push(x)
Xstruct value *x;		/* contains index of value to push; must be integer! */
X{
Xstatic char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
Xregister int index;
X
X	if (x->type != INT)
X		int_error("internal error--non-int passed to f_push!",NO_CARET);
X	index = x->v.int_val;
X
X	if (vt[index].vt_undef) {	 /* undefined */
X		(void) strcpy(&err_str[sizeof(ERR_VAR) - 1], vt[index].vt_name);
X		int_error(err_str,NO_CARET);
X	}
X	push(&vt[index].vt_value);
X}
X
X
Xf_pushc(x)
Xstruct value *x;
X{
X	if (s_p == STACK_DEPTH - 1)
X		int_error("stack overflow",NO_CARET);
X	stack[++s_p] = *x;
X}
X
X
Xf_pushd(x)
Xstruct value *x;
X{
X	f_pushc(&udft[x->v.int_val].dummy_value);
X}
X
X
X#define ERR_FUN "undefined function: "
X
Xf_call(f_index)  /* execute a udf */
Xstruct value *f_index;
X{
Xstatic char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
X
X	if (udft[f_index->v.int_val].at.count == 0) { /* undefined */
X		(void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
X				udft[f_index->v.int_val].udft_name);
X		int_error(err_str,NO_CARET);
X	}
X	(void) pop(&udft[f_index->v.int_val].dummy_value);
X
X	execute_at(&udft[f_index->v.int_val].at);
X}
X
X
Xstatic int_check(v)
Xstruct value *v;
X{
X	if (v->type != INT)
X		int_error("non-integer passed to boolean operator",NO_CARET);
X}
X
X
Xf_terniary()		/* code for (a) ? b : c */
X{
Xstruct value a, b, c;
X	(void) pop(&c);	(void) pop(&b);	int_check(pop(&a));
X	push((a.v.int_val) ? &b : &c);
X			/* I just had to use ? : here! */
X}
X
X
Xf_lnot()
X{
Xstruct value a;
X	int_check(pop(&a));
X	push(integer(&a,!a.v.int_val) );
X}
X
X
Xf_bnot()
X{
Xstruct value a;
X	int_check(pop(&a));
X	push( integer(&a,~a.v.int_val) );
X}
X
X
Xf_lor()
X{
Xstruct value a,b;
X	int_check(pop(&b));
X	int_check(pop(&a));
X	push( integer(&a,a.v.int_val || b.v.int_val) );
X}
X
X
Xf_land()
X{
Xstruct value a,b;
X	int_check(pop(&b));
X	int_check(pop(&a));
X	push( integer(&a,a.v.int_val && b.v.int_val) );
X}
X
X
Xf_bor()
X{
Xstruct value a,b;
X	int_check(pop(&b));
X	int_check(pop(&a));
X	push( integer(&a,a.v.int_val | b.v.int_val) );
X}
X
X
Xf_xor()
X{
Xstruct value a,b;
X	int_check(pop(&b));
X	int_check(pop(&a));
X	push( integer(&a,a.v.int_val ^ b.v.int_val) );
X}
X
X
Xf_band()
X{
Xstruct value a,b;
X	int_check(pop(&b));
X	int_check(pop(&a));
X	push( integer(&a,a.v.int_val & b.v.int_val) );
X}
X
X
Xf_uminus()
X{
Xstruct value a;
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			a.v.int_val = -a.v.int_val;
X			break;
X		case CMPLX:
X			a.v.cmplx_val.real =
X				-a.v.cmplx_val.real;
X			a.v.cmplx_val.imag =
X				-a.v.cmplx_val.imag;
X	}
X	push(&a);
X}
X
X
Xf_eq() /* note: floating point equality is rare because of roundoff error! */
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val ==
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val ==
X						b.v.cmplx_val.real &&
X					   b.v.cmplx_val.imag == 0.0);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (b.v.int_val == a.v.cmplx_val.real &&
X					   a.v.cmplx_val.imag == 0.0);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real==
X						b.v.cmplx_val.real &&
X						a.v.cmplx_val.imag==
X						b.v.cmplx_val.imag);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_ne()
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val !=
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val !=
X						b.v.cmplx_val.real ||
X					   b.v.cmplx_val.imag != 0.0);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (b.v.int_val !=
X						a.v.cmplx_val.real ||
X					   a.v.cmplx_val.imag != 0.0);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real !=
X						b.v.cmplx_val.real ||
X						a.v.cmplx_val.imag !=
X						b.v.cmplx_val.imag);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_gt()
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val >
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val >
X						b.v.cmplx_val.real);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (a.v.cmplx_val.real >
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real >
X						b.v.cmplx_val.real);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_lt()
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val <
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val <
X						b.v.cmplx_val.real);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (a.v.cmplx_val.real <
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real <
X						b.v.cmplx_val.real);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_ge()
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val >=
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val >=
X						b.v.cmplx_val.real);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (a.v.cmplx_val.real >=
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real >=
X						b.v.cmplx_val.real);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_le()
X{
Xstruct value a, b;
X	register int result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					result = (a.v.int_val <=
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.int_val <=
X						b.v.cmplx_val.real);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					result = (a.v.cmplx_val.real <=
X						b.v.int_val);
X					break;
X				case CMPLX:
X					result = (a.v.cmplx_val.real <=
X						b.v.cmplx_val.real);
X			}
X	}
X	push(integer(&a,result));
X}
X
X
Xf_plus()
X{
Xstruct value a, b, result;
X	(void) pop(&b);
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					(void) integer(&result,a.v.int_val +
X						b.v.int_val);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.int_val +
X						b.v.cmplx_val.real,
X					   b.v.cmplx_val.imag);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					(void) complex(&result,b.v.int_val +
X						a.v.cmplx_val.real,
X					   a.v.cmplx_val.imag);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.cmplx_val.real+
X						b.v.cmplx_val.real,
X						a.v.cmplx_val.imag+
X						b.v.cmplx_val.imag);
X			}
X	}
X	push(&result);
X}
X
X
Xf_minus()
X{
Xstruct value a, b, result;
X	(void) pop(&b);
X	(void) pop(&a);		/* now do a - b */
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					(void) integer(&result,a.v.int_val -
X						b.v.int_val);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.int_val -
X						b.v.cmplx_val.real,
X					   -b.v.cmplx_val.imag);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					(void) complex(&result,a.v.cmplx_val.real -
X						b.v.int_val,
X					    a.v.cmplx_val.imag);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.cmplx_val.real-
X						b.v.cmplx_val.real,
X						a.v.cmplx_val.imag-
X						b.v.cmplx_val.imag);
X			}
X	}
X	push(&result);
X}
X
X
Xf_mult()
X{
Xstruct value a, b, result;
X	(void) pop(&b);
X	(void) pop(&a);	/* now do a*b */
X
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					(void) integer(&result,a.v.int_val *
X						b.v.int_val);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.int_val *
X						b.v.cmplx_val.real,
X						a.v.int_val *
X						b.v.cmplx_val.imag);
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					(void) complex(&result,b.v.int_val *
X						a.v.cmplx_val.real,
X						b.v.int_val *
X						a.v.cmplx_val.imag);
X					break;
X				case CMPLX:
X					(void) complex(&result,a.v.cmplx_val.real*
X						b.v.cmplx_val.real-
X						a.v.cmplx_val.imag*
X						b.v.cmplx_val.imag,
X						a.v.cmplx_val.real*
X						b.v.cmplx_val.imag+
X						a.v.cmplx_val.imag*
X						b.v.cmplx_val.real);
X			}
X	}
X	push(&result);
X}
X
X
Xf_div()
X{
Xstruct value a, b, result;
Xregister double square;
X	(void) pop(&b);
X	(void) pop(&a);	/* now do a/b */
X
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					if (b.v.int_val)
X					  (void) integer(&result,a.v.int_val /
X						b.v.int_val);
X					else {
X					  (void) integer(&result,0);
X					  undefined = TRUE;
X					}
X					break;
X				case CMPLX:
X					square = b.v.cmplx_val.real*
X						b.v.cmplx_val.real +
X						b.v.cmplx_val.imag*
X						b.v.cmplx_val.imag;
X					if (square)
X						(void) complex(&result,a.v.int_val*
X						b.v.cmplx_val.real/square,
X						-a.v.int_val*
X						b.v.cmplx_val.imag/square);
X					else {
X						(void) complex(&result,0.0,0.0);
X						undefined = TRUE;
X					}
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					if (b.v.int_val)
X					  
X					  (void) complex(&result,a.v.cmplx_val.real/
X						b.v.int_val,
X						a.v.cmplx_val.imag/
X						b.v.int_val);
X					else {
X						(void) complex(&result,0.0,0.0);
X						undefined = TRUE;
X					}
X					break;
X				case CMPLX:
X					square = b.v.cmplx_val.real*
X						b.v.cmplx_val.real +
X						b.v.cmplx_val.imag*
X						b.v.cmplx_val.imag;
X					if (square)
X					(void) complex(&result,(a.v.cmplx_val.real*
X						b.v.cmplx_val.real+
X						a.v.cmplx_val.imag*
X						b.v.cmplx_val.imag)/square,
X						(a.v.cmplx_val.imag*
X						b.v.cmplx_val.real-
X						a.v.cmplx_val.real*
X						b.v.cmplx_val.imag)/
X							square);
X					else {
X						(void) complex(&result,0.0,0.0);
X						undefined = TRUE;
X					}
X			}
X	}
X	push(&result);
X}
X
X
Xf_mod()
X{
Xstruct value a, b;
X	(void) pop(&b);
X	(void) pop(&a);	/* now do a%b */
X
X	if (a.type != INT || b.type != INT)
X		int_error("can only mod ints",NO_CARET);
X	if (b.v.int_val)
X		push(integer(&a,a.v.int_val % b.v.int_val));
X	else {
X		push(integer(&a,0));
X		undefined = TRUE;
X	}
X}
X
X
Xf_power()
X{
Xstruct value a, b, result;
Xregister int i, t, count;
Xregister double mag, ang;
X	(void) pop(&b);
X	(void) pop(&a);	/* now find a**b */
X
X	switch(a.type) {
X		case INT:
X			switch (b.type) {
X				case INT:
X					count = abs(b.v.int_val);
X					t = 1;
X					for(i=0; i < count; i++)
X						t *= a.v.int_val;
X					if (b.v.int_val >= 0)
X						(void) integer(&result,t);
X					else
X						(void) complex(&result,1.0/t,0.0);
X					break;
X				case CMPLX:
X					mag =
X					  pow(magnitude(&a),fabs(b.v.cmplx_val.real));
X					if (b.v.cmplx_val.real < 0.0)
X						mag = 1.0/mag;
X					ang = angle(&a)*b.v.cmplx_val.real+
X					  b.v.cmplx_val.imag;
X					(void) complex(&result,mag*cos(ang),
X						mag*sin(ang));
X			}
X			break;
X		case CMPLX:
X			switch (b.type) {
X				case INT:
X					/* not so good, but...! */
X					mag =
X					  pow(magnitude(&a),(double)abs(b.v.int_val));
X					if (b.v.int_val < 0)
X						mag = 1.0/mag;
X					ang = angle(&a)*b.v.int_val;
X					(void) complex(&result,mag*cos(ang),
X						mag*sin(ang));
X					break;
X				case CMPLX:
X					mag =
X					  pow(magnitude(&a),fabs(b.v.cmplx_val.real));
X					if (b.v.cmplx_val.real < 0.0)
X					  mag = 1.0/mag;
X					ang = angle(&a)*b.v.cmplx_val.real+
X					  b.v.cmplx_val.imag;
X					(void) complex(&result,mag*cos(ang),
X						mag*sin(ang));
X			}
X	}
X	push(&result);
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'lasergnu'
then
	echo shar: will not over-write existing file "'lasergnu'"
else
sed 's/^X//' << \SHAR_EOF > 'lasergnu'
X#! /bin/csh -f
X#
X# Print gnutex output on an Imagen laser printer.
X
X# Plot-program-independent stuff
Xset iflags = ()		# arguments given to ipr
Xset hold = "inputbin 1"	# hold == manual => Hold output; feed paper manually.
X			# Default is to feed paper automatically.
Xset print_banner = on	# Print a banner page unless told otherwise.
Xunset input_file	# the plot input command file
Xset output_file = ()	# the output file (used only by the old laserism)
Xset plot_args = (-p)	# arguments to the plotting program (if any)
Xunset plot_command	# command line arguments may be plot commands
Xif !($?LASER) then
X	set LASER = "imagen018"
Xendif
Xset printer = (-P$LASER)	# Default printer set by shell variable LASER.
X
X# Plot-program-dependent stuff
Xset TMP=/tmp/gnu$$
Xecho "set term tek40xx" > $TMP
X
X# Loop through the command-line arguments.
X
Xtop:
X	if ($#argv > 0) then
X
X		switch ("$argv[1]")
X
X		case -b*:	# Do not print a banner page.
X		case -J*:	# Compatible with imprint.
X			set print_banner = off
X			shift argv
X			goto top
X
X		case -f?*:	# Specify file containing plot commands
X			set input_file = `echo $argv[1] | sed 's/^-f//'`
X			shift argv
X			goto top
X
X		case -f:	# Specify file containing plot commands
X			shift argv
X			if ($#argv > 0) then
X				set input_file = ($argv[1])
X				shift argv
X			else
X				echo "Usage: -f file ..."
X				echo "Type    lasergnu -help    for help."
X				exit (1)
X			endif
X			goto top
X
X		case -t?*:	# Specify title of plot
X			echo set title \""`echo $argv[1] | sed 's/^-t//'`"\" >> $TMP
X			shift argv
X			goto top
X
X		case -t:	# Specify title of plot
X			shift argv
X			if ($#argv > 0) then
X				echo set title \""$1"\" >> $TMP
X				shift argv
X			else
X				echo "Usage: -t title ..."
X				echo "Type    lasergnu -help    for help."
X				exit (1)
X			endif
X			goto top
X		case -hold:	# Hold output; feed the paper manually.
X			set hold = "inputbin manual"
X			shift argv
X			goto top
X
X          case -help:
X			echo "usage: lasergnu [-Pprinter] [-b] [-l] [-t title] [-f file] ['plot command']...."
X			exit(1)
X
X		case -l:
X			set plot_args = ($plot_args -l)
X			shift argv
X			goto top
X
X		case -P?*:	# Set the printer, exactly as by itroff.
X			set printer = $argv[1]
X			shift argv
X			goto top
X
X		case -P:	# Set the printer, exactly as by itroff.
X			shift argv
X			if ($#argv > 0) then
X				set printer = (-P$argv[1])
X				shift argv
X			else
X				echo "Usage: -P printer ..."
X				echo "Type    lasergnu -help    for help."
X				exit (1)
X			endif
X			goto top
X
X		case -?*:
X			echo "I do not recognize option $argv[1]."
X			echo "usage: lasergnu [-Pprinter] [-b] [-l] [-t title] [-f file] ['plot command']...."
X			exit (1)
X
X		default:
X	          echo "$argv[1]"	>> $TMP
X			set plot_command=1
X			shift argv
X			goto top
X
X		endsw
X	endif
X
X# If input file is specified AND command line contains plot commands, then
X#	do command line args first, then plot commands in input file.
Xif ($?input_file) then
X	cat $input_file >> $TMP
Xendif
X# The printer is whatever printer was last specified,
X# or the default printer if none was specified.
X
Xset iflags = ($iflags $printer)
X
Xif ($?plot_command) then
X	/usr/local/bin/gnutex $plot_args < $TMP | /usr/local/bin/ipr -Ltektronix \
X				$iflags -f gnutex \
X              			-D"jobheader $print_banner" \
X              			-D"program lasergnu"
Xelse
X#    cat $TMP - | /usr/local/bin/gnutex $plot_args | /usr/local/bin/ipr -Ltektronix \
X	cat $TMP | /usr/local/bin/gnutex $plot_args | /usr/local/bin/ipr -Ltektronix \
X				$iflags -f gnutex \
X              			-D"jobheader $print_banner" \
X              			-D"program lasergnu" 
Xendif
Xrm $TMP
SHAR_EOF
chmod +x 'lasergnu'
fi # end of overwriting check
if test -f 'misc.c'
then
	echo shar: will not over-write existing file "'misc.c'"
else
sed 's/^X//' << \SHAR_EOF > 'misc.c'
X/*
X *
X *    G N U P L O T  --  misc.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#include <stdio.h>
X#include "plot.h"
X
Xextern BOOLEAN screen_ok;
X
Xextern struct curve_points plot[];
Xextern int c_token,next_value,next_function;
Xextern struct udft_entry udft[];
Xextern struct at_type *curr_at;
Xextern struct ft_entry ft[];
Xextern struct vt_entry vt[];
X
Xchar *malloc();
X
X
Xpointmem(samples)
Xint samples;
X{
Xregister int i;
X	for (i = MAX_PLOTS-1; i >= 0; i--)
X		if (plot[i].points != NULL) {
X			free(plot[i].points);
X			plot[i].points = NULL;
X		}
X	for (i = 0; i < MAX_PLOTS; i++)
X		if ((plot[i].points = (struct coordinate *)
X			malloc((samples+1) * sizeof(struct coordinate))) == NULL) {
X				fprintf(stderr,"only space for %d plots\n",i);
X				screen_ok = FALSE;
X				break;
X			}
X}
X
X
Xsave_functions(fp)
XFILE *fp;
X{
Xint i;
X	
X	if (fp == 0)
X		os_error("Cannot open save file",c_token);			
X	else {
X		for (i=0; i < next_function; i++)
X			fprintf(fp,"%s\n",udft[i].definition);
X	}
X	(void) fclose(fp);
X}
X
X
Xsave_variables(fp)
XFILE *fp;
X{
Xint i;
X
X	if (fp == 0) 
X		os_error("Cannot open save file",c_token);			
X	else {
X		for (i=0; i < next_value; i++) {
X			fprintf(fp,"%s = ",vt[i].vt_name);
X			show_value(fp,&vt[i].vt_value);
X			(void) putc('\n',fp);
X		}
X	}
X	(void) fclose(fp);
X}
X
X
Xsave_all(fp)
XFILE *fp;
X{
Xint i;
X
X	if (fp == 0) 
X		os_error("Cannot open save file",c_token);			
X	else {
X		for (i=0; i < next_function; i++)
X			fprintf(fp,"%s\n",udft[i].definition);
X		for (i=0; i < next_value; i++) {
X			fprintf(fp,"%s = ",vt[i].vt_name);
X			show_value(fp,&vt[i].vt_value);
X			(void) putc('\n',fp);
X		}
X	}
X	(void) fclose(fp);
X}
X
X
Xload_file(fp)
XFILE *fp;
X{
Xregister int len;
Xextern char input_line[];
X
Xint start, left;
Xint more;
Xint stop = FALSE;
X
X	if ( fp == 0 ) 
X		os_error("Cannot open load file",c_token);
X	else {
X	    while (!stop) {		/* read all commands in file */
X		   /* read one command */
X		   left = MAX_LINE_LEN;
X		   start = 0;
X		   more = TRUE;
X
X		   while (more) {
X			  if (fgets(&(input_line[start]), left, fp) == NULL) {
X				 stop = TRUE; /* EOF in file */
X				 input_line[start] = '\0';
X				 more = FALSE;	
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		   if (strlen(input_line) > 0) {
X			  screen_ok = FALSE;	/* make sure command line is
X								   echoed on error */
X			  do_line();
X		   }
X	    }
X	}
X 	(void) fclose(fp);
X}
X
X
X
Xview_variables()
X{
Xint i;
X
X	screen_ok = FALSE;
X	fprintf(stderr,"\nVariables:\n");
X	for (i=0; i < next_value; i++) {
X		fprintf(stderr,"%-*s ",MAX_ID_LEN,vt[i].vt_name);
X		if (vt[i].vt_undef)
X			fputs("is undefined\n",stderr);
X		else {
X			fputs("= ",stderr);
X			show_value(stderr,&vt[i].vt_value);
X			(void) putc('\n',stderr);
X		}
X	}
X	(void) putc('\n',stderr);
X}
X
X
Xview_functions()
X{
Xint i;
X	screen_ok = FALSE;
X	fprintf(stderr,"\nUser-Defined Functions:\n");
X	for (i=0; i < next_function; i++) 
X		if (udft[i].at.count == 0) 
X			fprintf(stderr,"%s is undefined\n",udft[i].udft_name);
X		else
X			fprintf(stderr,"%s\n",udft[i].definition);
X	(void) putc('\n',stderr);
X}
X
X
Xview_at()
X{
Xstatic struct at_type at;
X	screen_ok = FALSE;
X	build_at(&at);		/* build action table in at */
X	(void) putc('\n',stderr);
X	show_at(0);
X	(void) putc('\n',stderr);
X}
X
X
Xshow_at(level)
Xint level;
X{
Xstruct at_type *at_address;
Xint i, j;
Xstruct value *arg;
X
X	at_address = curr_at;
X	for (i = 0; i < at_address->count; i++) {
X		for (j = 0; j < level; j++)
X			(void) putc(' ',stderr);	/* indent */
X
X			/* print name of action instruction */
X		fputs(ft[at_address->actions[i].index].ft_name,stderr);
X		arg = &(at_address->actions[i].arg);
X			/* now print optional argument */
X
X		switch(at_address->actions[i].index) {
X		  case (int)PUSH:	fprintf(stderr," (%s)\n",
X					  vt[arg->v.int_val].vt_name);
X					break;
X		  case (int)PUSHC:	(void) putc('(',stderr);
X					show_value(stderr,arg);
X					fputs(")\n",stderr);
X					break;
X		  case (int)PUSHD:	fprintf(stderr," (%s dummy)\n",
X					  udft[arg->v.int_val].udft_name);
X					break;
X		  case (int)CALL:	fprintf(stderr," (%s)\n",
X					  udft[arg->v.int_val].udft_name);
X					curr_at = &udft[arg->v.int_val].at;
X					show_at(level+2); /* recurse! */
X					curr_at = at_address;
X					break;
X		  default:
X					(void) putc('\n',stderr);
X		}
X	}
X}
X
X#ifdef vms
X#define OS "vms"
X#endif
X
X#ifdef unix
X#define OS "unix"
X#endif
X
X#ifdef MSDOS
X#define OS "MS-DOS"
X#endif
X
X#ifndef OS
X#define OS ""
X#endif
X
Xshow_version()
X{
X	extern char version[];
X	extern char date[];
X	screen_ok = FALSE;
X	fprintf(stderr,"%s v%s (%s);  %s\n\n", PROGRAM, version, OS, date);
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'parse.c'
then
	echo shar: will not over-write existing file "'parse.c'"
else
sed 's/^X//' << \SHAR_EOF > 'parse.c'
X/*
X *
X *    G N U P L O T  --  parse.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 <setjmp.h>
X#include <signal.h>
X#include <errno.h>
X#include "plot.h"
X
Xextern BOOLEAN undefined;
X
X#ifndef vms
Xextern int errno;
X#endif
X
Xextern int next_function,c_function /* next available space in udft */;
Xextern int num_tokens,c_token;
Xextern struct lexical_unit token[];
Xextern char dummy_var[];
Xextern struct at_type *curr_at;
X
Xstruct value *pop(),*integer(),*complex();
X
Xstatic struct at_type temp_at;
Xstatic jmp_buf fpe_env;
X
X#define dummy (struct value *) 0
X
Xfpe()
X{
X	(void) signal(SIGFPE, fpe);
X	undefined = TRUE;
X	longjmp(fpe_env, TRUE);
X}
X
Xevaluate_at(at,valptr)
Xstruct at_type *at;
Xstruct value *valptr;
X{
X	undefined = FALSE;
X	errno = 0;
X	reset_stack();
X	if (setjmp(fpe_env))
X		return;				/* just bail out */
X	(void) signal(SIGFPE, fpe);	/* catch core dumps on FPEs */
X
X	execute_at(at);
X
X	(void) signal(SIGFPE, SIG_DFL);
X
X	if (errno == EDOM || errno == ERANGE) {
X		undefined = TRUE;
X	} else {
X		(void) pop(valptr);
X		check_stack();
X	}
X}
X
X
Xstruct value *
Xconst_express(valptr)
Xstruct value *valptr;
X{
Xregister int tkn = c_token;
X	if (END_OF_COMMAND)
X		int_error("constant expression required",c_token);
X	build_at(&temp_at);	/* make a temporary action table */
X	evaluate_at(&temp_at,valptr);	/* run it and send answer back */
X	if (undefined) {
X		int_error("undefined value",tkn);
X	}
X	return(valptr);
X}
X
X
Xbuild_at(at)	/* build full expressions */
Xstruct at_type *at;
X{
X	curr_at = at;		/* set global variable */
X	curr_at->count = 0;		/* reset action table !!! */
X	express();
X}
X
X
Xexpress()  /* full expressions */
X{
X	xterm();
X	xterms();
X}
X
Xxterm()  /* NEW!  ? : expressions */
X{
X	aterm();
X	aterms();
X}
X
X
Xaterm()
X{
X	bterm();
X	bterms();
X}
X
X
Xbterm()
X{
X	cterm();
X	cterms();
X}
X
X
Xcterm()
X{
X	dterm();
X	dterms();
X}
X
X
Xdterm()
X{	
X	eterm();
X	eterms();
X}
X
X
Xeterm()
X{
X	fterm();
X	fterms();
X}
X
X
Xfterm()
X{
X	gterm();
X	gterms();
X}
X
X
Xgterm()
X{
X	hterm();
X	hterms();
X}
X
X
Xhterm()
X{
X	unary(); /* - things */
X	iterms(); /* * / % */
X}
X
X
Xfactor()
X{
Xregister int value;
Xstruct value a, real_value;
X
X	if (equals(c_token,"(")) {
X		c_token++;
X		express();
X		if (!equals(c_token,")")) 
X			int_error("')' expected",c_token);
X		c_token++;
X	}
X	else if (isnumber(c_token)) {
X		convert(&real_value,c_token);
X		c_token++;
X		add_action(PUSHC, &real_value);
X	}
X	else if (isletter(c_token)) {
X		if ((c_token+1 < num_tokens)  && equals(c_token+1,"(")) {
X		value = standard(c_token);
X			if (value) {	/* it's a standard function */
X				c_token += 2;
X				express();
X				if (!equals(c_token,")"))
X					int_error("')' expected",c_token);
X				c_token++;
X				add_action(value,dummy);
X			}
X			else {
X				value = user_defined(c_token);
X				c_token += 2;
X				express();
X				if (!equals(c_token,")")) 
X					int_error("')' expected",c_token);
X				c_token++;
X				add_action(CALL,integer(&a,value));
X			}
X		}
X		else {
X			if (equals(c_token,dummy_var)) {
X				value = c_function;
X				c_token++;
X				add_action(PUSHD,integer(&a,value));
X			}
X			else {
X				value = add_value(c_token);
X				c_token++;
X				add_action(PUSH,integer(&a,value));
X			}
X		}
X	} /* end if letter */
X	else
X		int_error("invalid expression ",c_token);
X
X	/* add action code for ** operator */
X	if (equals(c_token,"**")) {
X			c_token++;
X			unary();
X			add_action(POWER,dummy);
X	}
X}
X
X
X
Xxterms()
X{  /* create action code for ? : expressions */
X
X	while (equals(c_token,"?")) {
X		c_token++;
X		express();
X		if (!equals(c_token,":")) 
X			int_error("expecting ':'",c_token);
X		c_token++;
X		express();
X		add_action(TERNIARY,dummy);
X	}
X}
X
X
Xaterms()
X{  /* create action codes for || operator */
X
X	while (equals(c_token,"||")) {
X		c_token++;
X		aterm();
X		add_action(LOR,dummy);
X	}
X}
X
X
Xbterms()
X{ /* create action code for && operator */
X
X	while (equals(c_token,"&&")) {
X		c_token++;
X		bterm();
X		add_action(LAND,dummy);
X	}
X}
X
X
Xcterms()
X{ /* create action code for | operator */
X
X	while (equals(c_token,"|")) {
X		c_token++;
X		cterm();
X		add_action(BOR,dummy);
X	}
X}
X
X
Xdterms()
X{ /* create action code for ^ operator */
X
X	while (equals(c_token,"^")) {
X		c_token++;
X		dterm();
X		add_action(XOR,dummy);
X	}
X}
X
X
Xeterms()
X{ /* create action code for & operator */
X
X	while (equals(c_token,"&")) {
X		c_token++;
X		eterm();
X		add_action(BAND,dummy);
X	}
X}
X
X
Xfterms()
X{ /* create action codes for == and != operators */
X
X	while (TRUE) {
X		if (equals(c_token,"==")) {
X			c_token++;
X			fterm();
X			add_action(EQ,dummy);
X		}
X		else if (equals(c_token,"!=")) {
X			c_token++;
X			fterm(); 
X			add_action(NE,dummy); 
X		}
X		else break;
X	}
X}
X
X
Xgterms()
X{ /* create action code for < > >= or <= operators */
X	
X	while (TRUE) {
X		/* I hate "else if" statements */
X		if (equals(c_token,">")) {
X			c_token++;
X			gterm();
X			add_action(GT,dummy);
X		}
X		else if (equals(c_token,"<")) {
X			c_token++;
X			gterm();
X			add_action(LT,dummy);
X		}		
X		else if (equals(c_token,">=")) {
X			c_token++;
X			gterm();
X			add_action(GE,dummy);
X		}
X		else if (equals(c_token,"<=")) {
X			c_token++;
X			gterm();
X			add_action(LE,dummy);
X		}
X		else break;
X	}
X
X}
X
X
X
Xhterms()
X{ /* create action codes for + and - operators */
X
X	while (TRUE) {
X			if (equals(c_token,"+")) {
X				c_token++;
X				hterm();
X				add_action(PLUS,dummy);
X			}
X			else if (equals(c_token,"-")) {
X				c_token++;
X				hterm();
X				add_action(MINUS,dummy);
X			}
X			else break;
X	}
X}
X
X
Xiterms()
X{ /* add action code for * / and % operators */
X
X	while (TRUE) {
X			if (equals(c_token,"*")) {
X				c_token++;
X				unary();
X				add_action(MULT,dummy);
X			}
X			else if (equals(c_token,"/")) {
X				c_token++;
X				unary();
X				add_action(DIV,dummy);
X			}
X			else if (equals(c_token,"%")) {
X				c_token++;
X				unary();
X				add_action(MOD,dummy);
X			}
X			else break;
X	}
X}
X
X
Xunary()
X{ /* add code for unary operators */
X	if (equals(c_token,"!")) {
X		c_token++;
X		unary();
X		add_action(LNOT,dummy);
X	}
X	else if (equals(c_token,"~")) {
X		c_token++;
X		unary();
X		add_action(BNOT,dummy);
X	}
X	else if (equals(c_token,"-")) {
X		c_token++;
X		unary();
X		add_action(UMINUS,dummy);
X	}
X	else 
X		factor();
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'plot.c'
then
	echo shar: will not over-write existing file "'plot.c'"
else
sed 's/^X//' << \SHAR_EOF > 'plot.c'
X/*
X *
X *    G N U P L O T  --  plot.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 <setjmp.h>
X#include <signal.h>
X#include "plot.h"
X
Xextern FILE *outfile;
Xextern int term;
X
X#ifndef STDOUT
X#define STDOUT 1
X#endif
X
Xjmp_buf env;
X
Xstruct value stack[STACK_DEPTH];
X
Xstruct lexical_unit token[MAX_TOKENS];
X
Xstruct value *integer(),*complex();
X
X
Xextern struct termentry term_tbl[];
X
Xextern f_push(),f_pushc(),f_pushd(),f_call(),f_terniary(),f_lnot(),f_bnot(),
X	f_uminus(),f_lor(),f_land(),f_bor(),f_xor(),f_band(),f_eq(),f_ne(),
X	f_gt(),f_lt(),f_ge(),f_le(),f_plus(),f_minus(),f_mult(),f_div(),
X	f_mod(),f_power();
X
Xextern f_real(),f_imag(),f_arg(),f_conjg(),f_sin(),f_cos(),f_tan(),f_asin(),
X	f_acos(),f_atan(),f_sinh(),f_cosh(),f_tanh(),f_int(),f_abs(),f_sgn(),
X	f_sqrt(),f_exp(),f_log10(),f_log(),f_besj0(),f_besj1(),f_besy0(),f_besy1(),
X	f_floor(),f_ceil();
X	
X
Xstruct ft_entry ft[] = {	/* built-in function table */
X
X/* internal functions: */
X	{"push", f_push},	{"pushc", f_pushc},	{"pushd", f_pushd},
X	{"call", f_call},	{"?:", f_terniary},	{"lnot", f_lnot},
X	{"bnot", f_bnot},	{"uminus", f_uminus},	{"lor", f_lor},
X	{"land", f_land},	{"bor", f_bor},		{"xor", f_xor},
X	{"band", f_band},	{"eq", f_eq},		{"ne", f_ne},
X	{"gt", f_gt},		{"lt", f_lt},		{"ge", f_ge},
X	{"le", f_le},		{"plus", f_plus},	{"minus", f_minus},
X	{"mult", f_mult},	{"div", f_div},		{"mod", f_mod},
X	{"power", f_power},
X
X/* standard functions: */
X	{"real", f_real},	{"imag", f_imag},	{"arg", f_arg},
X	{"conjg", f_conjg}, {"sin", f_sin},		{"cos", f_cos},
X	{"tan", f_tan},		{"asin", f_asin},	{"acos", f_acos},
X	{"atan", f_atan},	{"sinh", f_sinh},	{"cosh", f_cosh},
X	{"tanh", f_tanh},	{"int", f_int},		{"abs", f_abs},
X	{"sgn", f_sgn},		{"sqrt", f_sqrt},	{"exp", f_exp},
X	{"log10", f_log10},	{"log", f_log},		{"besj0", f_besj0},
X	{"besj1", f_besj1},	{"besy0", f_besy0},	{"besy1", f_besy1},
X	{"floor", f_floor},	{"ceil", f_ceil}, 	{NULL, NULL}
X};
X
Xstruct udft_entry udft[MAX_UDFS+1];
X
Xstruct vt_entry vt[MAX_VALUES] = {
X	{"pi"},			{"xmin"},		{"xmax"},
X	{"ymin"}, 		{"ymax"},		{"autoscale"}
X};
X
Xstruct st_entry st[MAX_STYLES] = {
X    /* include the fixed styles by default */
X    /* These must match the positions in enum PLOT_STYLE */
X    {"lines"},	 	{"points"},		{"impulses"},		{"linespoints"},
X    {"dots"}
X};
Xint next_style = FIXED_STYLES+1;
X
X#ifdef vms
X
X#define HOME "sys$login:"
X
X#else /* vms */
X#ifdef MSDOS
X
X#define HOME "GNUTEX"
X
X#else /* MSDOS */
X
X#define HOME "HOME"
X
X#endif /* MSDOS */
X#endif /* vms */
X
X#ifdef unix
X#define PLOTRC ".gnutex"
X#else
X#define PLOTRC "gnutex.ini"
X#endif
X
Xint put_label=0;
Xint debug=0;
XBOOLEAN printer=0;			/* DFK 6/8/87 */
X
X#define print_debug(a)	if (debug) fprintf(stderr, a)
X
Xinterrupt()
X{
X	(void) signal(SIGINT, interrupt);
X	(void) signal(SIGFPE, SIG_DFL);	/* turn off FPE trapping */
X	if (term)
X		(*term_tbl[term].text)();	/* hopefully reset text mode */
X	(void) fflush(outfile);
X	(void) putc('\n',stderr);
X	longjmp(env, TRUE);		/* return to prompt */
X}
X
X
Xmain(argc, argv)
Xchar *argv[];
Xint argc;
X{
Xchar *getenv(),*strcat(),*strcpy();
XFILE *plotrc;
Xstatic char home[sizeof(PLOTRC)+40];
X
X/* Changes made 16 February 1987 by Nathan Hillery (nhh@duke)
X *	- to offer command line selection of various options, including:
X *		labels on plot
X *
X * Changes made 8 June 87 by David Kotz (dfk@duke)
X *   - to offer command line flag indicating output intended for printer,
X *     so first plot will not clear "screen" and waste paper
X */
X
Xchar	*s;
X/* Initialize flags */
X
Xwhile (--argc>0 && (*++argv)[0]=='-')
X	for (s=argv[0]+1; *s!='\0'; s++)
X		switch (*s) {
X			case 'l':
X			case 'L':
X				put_label=1;
X				print_debug("labels on\n");
X				break;
X			case 'p':		/* DFK 6/8/87 Don't waste page */
X				printer=1; /* if we are on a printer */
X				print_debug("printer mode on\n");
X				break;
X			case 'x':
X				debug=1;
X				print_debug("debugging on\n");
X				break;
X			default:
X				break;
X		}
X/* End changes made 16 February 1987 by Nathan Hillery (nhh@duke) */
X
X	setbuf(stderr,NULL);
X	outfile = fdopen(dup(STDOUT),"w");
X	(void) complex(&vt[(int)C_PI].vt_value, Pi, 0.0);
X
X	pointmem(SAMPLES);		/* malloc memory to keep plot points in */
X
X	if (!setjmp(env)) {		/* come back here from printerror() */
X		(void) signal(SIGINT, interrupt);	/* go there on interrupt char */
X		if (!(plotrc = (fopen(PLOTRC,"r")))) {
X#ifdef vms
X			(void) strcpy(home,HOME);
X			plotrc = fopen(strcat(home,PLOTRC),"r");
X#else
X			(void) strcat(strcpy(home,getenv(HOME)),"/");
X			plotrc = fopen(strcat(home,PLOTRC),"r");
X#endif /* vms */
X		}
X		if (plotrc)
X			load_file(plotrc);
X	}
X
Xloop:	com_line();
X	goto loop;
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'plot.h'
then
	echo shar: will not over-write existing file "'plot.h'"
else
sed 's/^X//' << \SHAR_EOF > 'plot.h'
X/*
X *
X *    G N U P L O T  --  plot.h
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 * 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#define PATCHLEVEL 0
X
X#define PROGRAM "gnutex"
X#define PROMPT "gnutex> "
X#define SHELL "/bin/sh"
X#ifdef vms
X#define HELP  ""
X#else /* vms */
X#define HELP  "echo Sorry, no help for gnutex"
X#endif
X
X#define TRUE 1
X#define FALSE 0
X
X#define Pi 3.141592653589793
X
X#define MAX_PLOTS 16			/* max number of overlapping plots */
X#define MAX_LINE_LEN 512	/* maximum number of chars allowed on line */
X#define MAX_TOKENS 200
X#define MAX_ID_LEN 200		/* max length of an identifier (long for files)*/
X
X#ifdef PC
X#define MAX_UDFS 30			/* max number of user-defined functions */
X#else /* PC */
X#define MAX_UDFS 100
X#endif /* PC */
X
X#define MAX_STYLES 20		/* max number of user-defined styles */
X#define MAX_KEYS 16			/* max number of entries in key */
X#define MAX_VALUES 50		/* max number of user-defined constants */
X#define MAX_AT_LEN 100		/* max number of entries in action table */
X#define STACK_DEPTH 100
X#define NO_CARET (-1)
X
X#define SAMPLES 160			/* default number of samples for a plot */
X#define ZERO	1e-8		/* default for 'zero' set option */
X
X/*
X * note about HUGE:  this number is just used as a flag for really
X *   big numbers, so it doesn't have to be the absolutely biggest number
X *   on the machine.
X */
X
X#ifdef PC
X#define  HUGE 1e38
X#endif /* PC */
X
X#define END_OF_COMMAND (c_token == num_tokens || equals(c_token,";"))
X#define push(arg) f_pushc(arg)	/* same thing! */
X
X#define top_of_stack stack[s_p]
X
Xtypedef int BOOLEAN;
Xtypedef int (*FUNC_PTR)();
X
Xenum {
X	C_PI, NEXT_VALUE
X};
X
Xenum operators {
X	PUSH, PUSHC, PUSHD, CALL, TERNIARY, LNOT, BNOT, UMINUS, LOR, LAND, BOR,
X	XOR, BAND, EQ, NE, GT, LT, GE, LE, PLUS, MINUS, MULT, DIV, MOD, POWER,
X	SF_START
X};
X
Xenum DATA_TYPES {
X	INT, CMPLX
X};
X
Xenum PLOT_TYPES {
X	FUNC, DATA
X};
X
Xenum PLOT_STYLE {
X	LINES, POINTS, IMPULSES, LINESPOINTS, DOTS
X};
X#define FIXED_STYLES ((int)DOTS) /* highest numbered fixed style */
X
Xstruct cmplx {
X	double real, imag;
X};
X
Xstruct value {
X	enum DATA_TYPES type;
X	union {
X		char *str_val;
X		int int_val;
X		struct cmplx cmplx_val;
X	} v;
X};
X
Xstruct lexical_unit {
X	BOOLEAN is_token;		/* true if token, false if a value */ 
X	struct value l_val;
X	int start_index;	/* index of first char in token */
X	int length;		/* length of token in chars */
X};
X
Xstruct at_entry {		/* action table entry */
X	int index;		/* index into function table */
X	struct value arg;
X};
X
Xstruct at_type {
X	int count;
X	struct at_entry actions[MAX_AT_LEN];
X};
X
Xstruct ft_entry {		/* standard function table entry */
X	char *ft_name;		/* pointer to name of this function */
X	FUNC_PTR funct;		/* address of function to call */
X};
X
Xstruct udft_entry {		/* user-defined function table entry */
X	char udft_name[MAX_ID_LEN+1];/* name of this function entry */
X	struct at_type at;	/* action table to execute */
X	char definition[MAX_LINE_LEN+1]; /* definition of function as typed */
X	struct value dummy_value;/* current value of dummy variable */
X};
X
Xstruct vt_entry {		/* value table entry */
X	char vt_name[MAX_ID_LEN+1];/* name of this value entry */
X	BOOLEAN vt_undef;		/* true if not defined yet */
X	struct value vt_value;	/* value it has */
X};
X
Xstruct st_entry {		/* style table entry */
X	char st_name[MAX_ID_LEN+1];/* name of this style entry */
X	BOOLEAN st_undef;		/* true if not defined yet */
X	char st_point[MAX_ID_LEN+1]; /* string for point */
X	float st_spacing;		/* spacing of seqence */
X	short st_length;		/* length of sequence */
X#define MAX_STYLE_SEQ_LENGTH 5
X	char st_seq[MAX_STYLE_SEQ_LENGTH][MAX_ID_LEN+1]; /* dot sequence */
X};
X
Xstruct coordinate {
X	BOOLEAN undefined;	/* TRUE if value off screen */
X#ifdef PC
X	float x, y;			/* memory is tight on PCs! */
X#else
X	double x, y;
X#endif /* PC */
X};
X
Xstruct curve_points {
X	enum PLOT_TYPES plot_type;
X	unsigned int plot_style;	/* now an int to include user-defined styles */
X	char title[MAX_LINE_LEN + 1];
X	int count;
X	struct coordinate *points;
X};
X
Xstruct termentry {
X	char name[MAX_ID_LEN + 1];
X	unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
X	FUNC_PTR init,reset,text,graphics,move,vector,linetype,lrput_text,
X		ulput_text,point;
X	FUNC_PTR xyput_text, xtick_text, ytick_text;
X	FUNC_PTR plotstyle;
X};
X
X/*
X * SS$_NORMAL is "normal completion", STS$M_INHIB_MSG supresses
X * printing a status message.
X * SS$_ABORT is the general abort status code.
X from:	Martin Minow
X	decvax!minow
X */
X#ifdef	vms
X#include		<ssdef.h>
X#include		<stsdef.h>
X#define	IO_SUCCESS	(SS$_NORMAL | STS$M_INHIB_MSG)
X#define	IO_ERROR	SS$_ABORT
X#endif /* vms */
X
X#ifndef	IO_SUCCESS	/* DECUS or VMS C will have defined these already */
X#define	IO_SUCCESS	0
X#endif
X#ifndef	IO_ERROR
X#define	IO_ERROR	1
X#endif
SHAR_EOF
fi # end of overwriting check
if test -f 'scanner.c'
then
	echo shar: will not over-write existing file "'scanner.c'"
else
sed 's/^X//' << \SHAR_EOF > 'scanner.c'
X/*
X *
X *    G N U P L O T  --  scanner.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 * 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 <ctype.h>
X#include "plot.h"
X
Xextern BOOLEAN screen_ok;
X
X#ifdef vms
X
X#include stdio
X#include descrip
X#include errno
X
X#define MAILBOX "PLOT$MAILBOX"
X#define pclose(f) fclose(f)
X
X#endif /* vms */
X
X
X#ifndef STDOUT
X#define STDOUT 1
X#endif
X
X#define LBRACE '{'
X#define RBRACE '}'
X
X#define APPEND_TOKEN {token[t_num].length++; current++;}
X
X#define SCAN_IDENTIFIER while (isalpha(expression[current + 1]) ||\
X			       isdigit(expression[current + 1]))\
X				APPEND_TOKEN
X
Xextern struct lexical_unit token[MAX_TOKENS];
X
Xstatic int t_num;	/* number of token I'm working on */
X
Xchar *strcat(), *strcpy();
X
X/*
X * scanner() breaks expression[] into lexical units, storing them in token[].
X *   The total number of tokens found is returned as the function value.
X *   Scanning will stop when '\0' is found in expression[], or when token[]
X *     is full.
X *
X *	 Scanning is performed by following rules:
X *
X *		Current char	token should contain
X *     -------------    -----------------------
X *		1.  alpha		all following alpha-numerics
X *		2.  digit		0 or more following digits, 0 or 1 decimal point,
X *						  0 or more digits, 0 or 1 'e' or 'E',
X *						  0 or more digits.
X *		3.  ^,+,-,/		only current char
X *		    %,~,(,)
X *		    [,],;,:,
X *		    ?,comma
X *		4.  &,|,=,*		current char; also next if next is same
X *		5.  !,<,>		current char; also next if next is =
X *		6.  ", '		all chars up until matching quote
X *        7.  #          this token cuts off scanning of the line (DFK).
X *
X *		white space between tokens is ignored
X */
Xscanner(expression)
Xchar expression[];
X{
Xregister int current;	/* index of current char in expression[] */
Xregister int quote;
Xchar brace;
X
X	for (current = t_num = 0;
X	    t_num < MAX_TOKENS && expression[current] != '\0';
X	    current++) {
Xagain:
X		if (isspace(expression[current]))
X			continue;						/* skip the whitespace */
X		token[t_num].start_index = current;
X		token[t_num].length = 1;
X		token[t_num].is_token = TRUE;	/* to start with...*/
X
X		if (expression[current] == '`') {
X			substitute(&expression[current],MAX_LINE_LEN - current);
X			goto again;
X		}
X		if (isalpha(expression[current])) {
X			SCAN_IDENTIFIER;
X		} else if (isdigit(expression[current]) ||
X			   expression[current] == '.') {
X			token[t_num].is_token = FALSE;
X			token[t_num].length = get_num(&expression[current]);
X			current += (token[t_num].length - 1);
X		} else if (expression[current] == LBRACE) {
X			token[t_num].is_token = FALSE;
X			token[t_num].l_val.type = CMPLX;
X			if ((sscanf(&expression[++current],"%lf , %lf %c",
X				&token[t_num].l_val.v.cmplx_val.real,
X				&token[t_num].l_val.v.cmplx_val.imag,
X				&brace) != 3) || (brace != RBRACE))
X					int_error("invalid complex constant",t_num);
X			token[t_num].length += 2;
X			while (expression[++current] != RBRACE) {
X				token[t_num].length++;
X				if (expression[current] == '\0')
X					int_error("no matching '}'", t_num);
X			}
X		} else if (expression[current] == '\'' || expression[current] == '\"') {
X			token[t_num].length++;
X			quote = expression[current];
X			while (expression[++current] != quote) {
X				if (expression[current] == '\0')
X					int_error("unmatched quote",t_num);
X				token[t_num].length++;
X			}
X		} else switch (expression[current]) {
X		    case '#':		/* DFK: add comments to gnutex */
X		    	 goto endline;	/* ignore the rest of the line */
X			case '^':
X			case '+':
X			case '-':
X			case '/':
X			case '%':
X			case '~':
X			case '(':
X			case ')':
X			case '[':
X			case ']':
X			case ';':
X			case ':':
X			case '?':
X			case ',':
X				break;
X			case '&':
X			case '|':
X			case '=':
X			case '*':
X				if (expression[current] ==
X				    expression[current + 1])
X					APPEND_TOKEN;
X				break;
X			case '!':
X			case '<':
X			case '>':
X				if (expression[current + 1] == '=')
X					APPEND_TOKEN;
X				break;
X			default:
X				int_error("invalid character",t_num);
X			}
X		++t_num;	/* next token if not white space */
X	}
X
Xendline:					/* comments jump here to ignore line */
X
X/* Now kludge an extra token which points to '\0' at end of expression[].
X   This is useful so printerror() looks nice even if we've fallen off the
X   line. */
X
X		token[t_num].start_index = current;
X		token[t_num].length = 0;
X	return(t_num);
X}
X
X
Xget_num(str)
Xchar str[];
X{
Xdouble atof();
Xregister int count = 0;
Xlong atol();
Xregister long lval;
X
X	token[t_num].is_token = FALSE;
X	token[t_num].l_val.type = INT;		/* assume unless . or E found */
X	while (isdigit(str[count]))
X		count++;
X	if (str[count] == '.') {
X		token[t_num].l_val.type = CMPLX;
X		while (isdigit(str[++count]))	/* swallow up digits until non-digit */
X			;
X		/* now str[count] is other than a digit */
X	}
X	if (str[count] == 'e' || str[count] == 'E') {
X		token[t_num].l_val.type = CMPLX;
X		if (str[++count] == '-')
X			count++;
X		if (!isdigit(str[count])) {
X			token[t_num].start_index += count;
X			int_error("expecting exponent",t_num);
X		}
X		while (isdigit(str[++count]))
X			;
X	}
X	if (token[t_num].l_val.type == INT) {
X 		lval = atol(str);
X		if ((token[t_num].l_val.v.int_val = lval) != lval)
X			int_error("integer overflow; change to floating point",t_num);
X	} else {
X		token[t_num].l_val.v.cmplx_val.imag = 0.0;
X		token[t_num].l_val.v.cmplx_val.real = atof(str);
X	}
X	return(count);
X}
X
X
X#ifdef MSDOS
X
Xsubstitute()
X{
X	int_error("substitution not supported by MS-DOS!",t_num);
X}
X
X#else /* MSDOS */
X
Xsubstitute(str,max)			/* substitute output from ` ` */
Xchar *str;
Xint max;
X{
Xregister char *last;
Xregister int i,c;
Xregister FILE *f;
XFILE *popen();
Xstatic char pgm[MAX_LINE_LEN],output[MAX_LINE_LEN];
X
X#ifdef vms
Xint chan;
Xstatic $DESCRIPTOR(pgmdsc,pgm);
Xstatic $DESCRIPTOR(lognamedsc,MAILBOX);
X#endif /* vms */
X
X	i = 0;
X	last = str;
X	while (*(++last) != '`') {
X		if (*last == '\0')
X			int_error("unmatched `",t_num);
X		pgm[i++] = *last;
X	}
X	pgm[i] = '\0';		/* end with null */
X	max -= strlen(last);	/* max is now the max length of output sub. */
X  
X#ifdef vms
X  	pgmdsc.dsc$w_length = i;
X   	if (!((vaxc$errno = sys$crembx(0,&chan,0,0,0,0,&lognamedsc)) & 1))
X   		os_error("sys$crembx failed",NO_CARET);
X   
X   	if (!((vaxc$errno = lib$spawn(&pgmdsc,0,&lognamedsc,&1)) & 1))
X   		os_error("lib$spawn failed",NO_CARET);
X   
X   	if ((f = fopen(MAILBOX,"r")) == NULL)
X   		os_error("mailbox open failed",NO_CARET);
X#else /* vms */
X  	if ((f = popen(pgm,"r")) == NULL)
X  		os_error("popen failed",NO_CARET);
X#endif /* vms */
X
X	i = 0;
X	while ((c = getc(f)) != EOF) {
X		output[i++] = ((c == '\n') ? ' ' : c);	/* newlines become blanks*/
X		if (i == max) {
X			(void) pclose(f);
X			int_error("substitution overflow", t_num);
X		}
X	}
X	(void) pclose(f);
X	if (i + strlen(last) > max)
X		int_error("substitution overflowed rest of line", t_num);
X	(void) strcpy(output+i,last+1);		/* tack on rest of line to output */
X	(void) strcpy(str,output);				/* now replace ` ` with output */
X	screen_ok = FALSE;
X}
X#endif /* MS-DOS */
SHAR_EOF
fi # end of overwriting check
if test -f 'standard.c'
then
	echo shar: will not over-write existing file "'standard.c'"
else
sed 's/^X//' << \SHAR_EOF > 'standard.c'
X/*
X *
X *    G N U P L O T  --  header.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#include <math.h>
X#include <stdio.h>
X#include "plot.h"
X
Xextern BOOLEAN undefined;
X
X#ifdef vms
X#include <errno.h>
X#else
Xextern int errno;
X#endif /* vms */
X
X
Xextern struct value stack[STACK_DEPTH];
Xextern int s_p;
X
Xstruct value *pop(), *complex(), *integer();
X
Xdouble magnitude(), angle(), real(), imag();
X
X
Xf_real()
X{
Xstruct value a;
X	push( complex(&a,real(pop(&a)), 0.0) );
X}
X
Xf_imag()
X{
Xstruct value a;
X	push( complex(&a,imag(pop(&a)), 0.0) );
X}
X
Xf_arg()
X{
Xstruct value a;
X	push( complex(&a,angle(pop(&a)), 0.0) );
X}
X
Xf_conjg()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,real(&a),-imag(&a) ));
X}
X
Xf_sin()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,sin(real(&a))*cosh(imag(&a)), cos(real(&a))*sinh(imag(&a))) );
X}
X
Xf_cos()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,cos(real(&a))*cosh(imag(&a)), -sin(real(&a))*sinh(imag(&a))));
X}
X
Xf_tan()
X{
Xstruct value a;
Xregister double den;
X	(void) pop(&a);
X	den = cos(2*real(&a))+cosh(2*imag(&a));
X	push( complex(&a,sin(2*real(&a))/den, sinh(2*imag(&a))/den) );
X}
X
Xf_asin()
X{
Xstruct value a;
Xregister double alpha, beta, x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0) {
X		if (fabs(x) > 1.0) {
X			undefined = TRUE;
X			push(complex(&a,0.0, 0.0));
X		} else
X			push( complex(&a,asin(x),0.0) );
X	} else {
X		beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
X		alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
X		push( complex(&a,asin(beta), log(alpha + sqrt(alpha*alpha-1))) );
X	}
X}
X
Xf_acos()
X{
Xstruct value a;
Xregister double alpha, beta, x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0) {
X		if (fabs(x) > 1.0) {
X			undefined = TRUE;
X			push(complex(&a,0.0, 0.0));
X		} else
X			push( complex(&a,acos(x),0.0) );
X	} else {
X		alpha = sqrt((x + 1)*(x + 1) + y*y)/2 + sqrt((x - 1)*(x - 1) + y*y)/2;
X		beta  = sqrt((x + 1)*(x + 1) + y*y)/2 - sqrt((x - 1)*(x - 1) + y*y)/2;
X		push( complex(&a,acos(beta), log(alpha + sqrt(alpha*alpha-1))) );
X	}
X}
X
Xf_atan()
X{
Xstruct value a;
Xregister double x, y;
X	(void) pop(&a);
X	x = real(&a); y = imag(&a);
X	if (y == 0.0)
X		push( complex(&a,atan(x), 0.0) );
X	else if (x == 0.0 && fabs(y) == 1.0) {
X		undefined = TRUE;
X		push(complex(&a,0.0, 0.0));
X	} else
X		push( complex(&a,atan(2*x/(1-x*x-y*y)),
X	    		log((x*x+(y+1)*(y+1))/(x*x+(y-1)*(y-1)))/4) );
X}
X
Xf_sinh()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,sinh(real(&a))*cos(imag(&a)), cosh(real(&a))*sin(imag(&a))) );
X}
X
Xf_cosh()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,cosh(real(&a))*cos(imag(&a)), sinh(real(&a))*sin(imag(&a))) );
X}
X
Xf_tanh()
X{
Xstruct value a;
Xregister double den;
X	(void) pop(&a);
X	den = cosh(2*real(&a)) + cos(2*imag(&a));
X	push( complex(&a,sinh(2*real(&a))/den, sin(2*imag(&a))/den) );
X}
X
Xf_int()
X{
Xstruct value a;
X	push( integer(&a,(int)real(pop(&a))) );
X}
X
X
Xf_abs()
X{
Xstruct value a;
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,abs(a.v.int_val)) );			
X			break;
X		case CMPLX:
X			push( complex(&a,magnitude(&a), 0.0) );
X	}
X}
X
Xf_sgn()
X{
Xstruct value a;
X	(void) pop(&a);
X	switch(a.type) {
X		case INT:
X			push( integer(&a,(a.v.int_val > 0) ? 1 : 
X					(a.v.int_val < 0) ? -1 : 0) );
X			break;
X		case CMPLX:
X			push( integer(&a,(a.v.cmplx_val.real > 0.0) ? 1 : 
X					(a.v.cmplx_val.real < 0.0) ? -1 : 0) );
X			break;
X	}
X}
X
X
Xf_sqrt()
X{
Xstruct value a;
X	double mag, ang;
X	(void) pop(&a);
X	mag = sqrt(magnitude(&a));
X	if ( (ang = angle(&a)) < 0.0)
X		ang += 2*Pi;
X	ang /= 2;
X	push( complex(&a,mag*cos(ang), mag*sin(ang)) );
X}
X
X
Xf_exp()
X{
Xregister double mag, ang;
Xstruct value a;
X	(void) pop(&a);
X	mag = exp(real(&a));
X	ang = imag(&a);
X	push( complex(&a,mag*cos(ang), mag*sin(ang)) );
X}
X
X
Xf_log10()
X{
Xstruct value a;
Xregister double l10;;
X	(void) pop(&a);
X	l10 = log(10.0);	/***** replace with a constant! ******/
X	push( complex(&a,log(magnitude(&a))/l10, angle(&a)/l10) );
X}
X
X
Xf_log()
X{
Xstruct value a;
X	(void) pop(&a);
X	push( complex(&a,log(magnitude(&a)), angle(&a)) );
X}
X
Xf_besj0()	/* j0(a) = sin(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_sin();
X	push(&a);
X	f_div();
X}
X
X
Xf_besj1()	/* j1(a) = sin(a)/(a**2) - cos(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_sin();
X	push(&a);
X	push(&a);
X	f_mult();
X	f_div();
X	push(&a);
X	f_cos();
X	push(&a);
X	f_div();
X	f_minus();
X}
X
X
Xf_besy0()	/* y0(a) = -cos(a)/a */
X{
Xstruct value a;
X	a = top_of_stack;
X	f_cos();
X	push(&a);
X	f_div();
X	f_uminus();
X}
X
X
Xf_besy1()	/* y1(a) = -cos(a)/(a**2) - sin(a)/a */
X{
Xstruct value a;
X
X	a = top_of_stack;
X	f_cos();
X	push(&a);
X	push(&a);
X	f_mult();
X	f_div();
X	push(&a);
X	f_sin();
X	push(&a);
X	f_div();
X	f_plus();
X	f_uminus();
X}
X
X
Xf_floor()
X{
Xstruct value a;
X
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,(int)floor((double)a.v.int_val)));			
X			break;
X		case CMPLX:
X			push( complex(&a,floor(a.v.cmplx_val.real),
X				floor(a.v.cmplx_val.imag)) );
X	}
X}
X
X
X
Xf_ceil()
X{
Xstruct value a;
X
X	(void) pop(&a);
X	switch (a.type) {
X		case INT:
X			push( integer(&a,(int)ceil((double)a.v.int_val)));			
X			break;
X		case CMPLX:
X			push( complex(&a,ceil(a.v.cmplx_val.real), ceil(a.v.cmplx_val.imag)) );
X	}
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'term.c'
then
	echo shar: will not over-write existing file "'term.c'"
else
sed 's/^X//' << \SHAR_EOF > 'term.c'
X/*
X *
X *    G N U P L O T  --  term.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 * 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 "plot.h"
X
X#define NICE_LINE		0
X#define POINT_TYPES		6
X
Xextern FILE *outfile;
Xextern BOOLEAN term_init;
Xextern int term;
X
Xextern BOOLEAN clipping;
X
Xextern char input_line[];
Xextern struct lexical_unit token[];
Xextern struct termentry term_tbl[];
X
X#ifdef PC
Xstatic int pattern[] = {0xffff, 0x0f0f, 0xffff, 0x3333, 0x3f3f};
X
X#ifdef CORONA
Xchar screen[65535];
X#endif /* CORONA */
X
Xint mask;
Xstatic int graphics_on = FALSE;
Xint startx, starty;
X
X#define EGA_XMAX 640
X#define EGA_YMAX 350
X
X#define EGA_XLAST (EGA_XMAX - 1)
X#define EGA_YLAST (EGA_YMAX - 1)
X
X#define EGA_VCHAR 14
X#define EGA_HCHAR 8
X#define EGA_VTIC 5
X#define EGA_HTIC 5
X
X
X#define CGA_XMAX 640
X#define CGA_YMAX 200
X
X#define CGA_XLAST (CGA_XMAX - 1)
X#define CGA_YLAST (CGA_YMAX - 1)
X
X#define CGA_VCHAR 8
X#define CGA_HCHAR 8
X#define CGA_VTIC 3
X#define CGA_HTIC 3
X
X#ifdef CORONA
X#define COR_XMAX 640
X#define COR_YMAX 325
X
X#define COR_XLAST (COR_XMAX - 1)
X#define COR_YLAST (COR_YMAX - 1)
X
X#define COR_VCHAR 13
X#define COR_HCHAR 8
X#define COR_VTIC 4
X#define COR_HTIC 4
X#endif /* CORONA */
X#endif /* PC */
X
X/*
X * general point routine
X */
Xline_and_point(x,y,number)
Xint x,y,number;
X{
X	/* temporary(?) kludge to allow terminals with bad linetypes 
X		to make nice marks */
X
X	(*term_tbl[term].linetype)(NICE_LINE);
X	do_point(x,y,number);
X}
X
Xdo_point(x,y,number)
Xint x,y;
Xint number;
X{
Xregister struct termentry *t;
Xregister int htic,vtic;
X
X	t = &term_tbl[term];
X
X    /* do just a DOT? */
X    if (number == -1) {
X	   (*t->move)(x,y);
X	   (*t->vector)(x,y);
X	   return;
X    }
X
X	number %= POINT_TYPES;
X	htic = (t->h_tic/2);	/* should be in term_tbl[] in later version */
X	vtic = (t->v_tic/2);	
X
X	if (clipping && (x < t->h_tic || y < t->v_tic || x >= t->xmax-t->h_tic ||
X		y >= t->ymax-t->v_tic) ) 
X		return;				/* add clipping in later version !!! */
X
X	switch(number) {
X		case 0: /* do diamond */ 
X				(*t->move)(x-htic,y);
X				(*t->vector)(x,y-vtic);
X				(*t->vector)(x+htic,y);
X				(*t->vector)(x,y+vtic);
X				(*t->vector)(x-htic,y);
X				(*t->move)(x,y);
X				(*t->vector)(x,y);
X				break;
X		case 1: /* do plus */ 
X				(*t->move)(x-htic,y);
X				(*t->vector)(x+htic,y);
X				(*t->move)(x,y-vtic);
X				(*t->vector)(x,y+vtic);
X				(*t->move)(x,y); /* DFK */
X				break;
X		case 2: /* do box */ 
X				(*t->move)(x-htic,y-vtic);
X				(*t->vector)(x+htic,y-vtic);
X				(*t->vector)(x+htic,y+vtic);
X				(*t->vector)(x-htic,y+vtic);
X				(*t->vector)(x-htic,y-vtic);
X				(*t->move)(x,y);
X				(*t->vector)(x,y);
X				break;
X		case 3: /* do X */ 
X				(*t->move)(x-htic,y-vtic);
X				(*t->vector)(x+htic,y+vtic);
X				(*t->move)(x-htic,y+vtic);
X				(*t->vector)(x+htic,y-vtic);
X				(*t->move)(x,y); /* DFK */
X				break;
X		case 4: /* do triangle */ 
X				(*t->move)(x,y+(4*vtic/3));
X				(*t->vector)(x-(4*htic/3),y-(2*vtic/3));
X				(*t->vector)(x+(4*htic/3),y-(2*vtic/3));
X				(*t->vector)(x,y+(4*vtic/3));
X				(*t->move)(x,y);
X				(*t->vector)(x,y);
X				break;
X		case 5: /* do star */ 
X				(*t->move)(x-htic,y);
X				(*t->vector)(x+htic,y);
X				(*t->move)(x,y-vtic);
X				(*t->vector)(x,y+vtic);
X				(*t->move)(x-htic,y-vtic);
X				(*t->vector)(x+htic,y+vtic);
X				(*t->move)(x-htic,y+vtic);
X				(*t->vector)(x+htic,y-vtic);
X				(*t->move)(x,y); /* DFK */
X				break;
X	}
X}
X
X
X
X#define AED_XMAX 768
X#define AED_YMAX 575
X
X#define AED_XLAST (AED_XMAX - 1)
X#define AED_YLAST (AED_YMAX - 1)
X
X#define AED_VCHAR	13
X#define AED_HCHAR	8
X#define AED_VTIC	8
X#define AED_HTIC	7
X
X
X
X
X#define HP75_XMAX 6000
X#define HP75_YMAX 6000
X
X#define HP75_XLAST (HP75_XMAX - 1)
X#define HP75_YLAST (HP75_XMAX - 1)
X
X/* HP75_VCHAR, HP75_HCHAR  are not used */
X#define HP75_VCHAR	(HP75_YMAX/20)	
X#define HP75_HCHAR	(HP75_XMAX/20)		
X#define HP75_VTIC	(HP75_YMAX/70)		
X#define HP75_HTIC	(HP75_XMAX/75)		
X
X
X
X
X#define REGISXMAX 800             
X#define REGISYMAX 440
X
X#define REGISXLAST (REGISXMAX - 1)
X#define REGISYLAST (REGISYMAX - 1)
X
X#define REGISVCHAR		20  	
X#define REGISHCHAR		8		
X#define REGISVTIC		8
X#define REGISHTIC		6
X
X
X
X#define QMS_XMAX 9000
X#define QMS_YMAX 6000
X
X#define QMS_XLAST (QMS_XMAX - 1)
X#define QMS_YLAST (QMS_YMAX - 1)
X
X#define QMS_VCHAR		120
X#define QMS_HCHAR		75
X#define QMS_VTIC		70
X#define QMS_HTIC		70
X
X
X
X
X#define TEK40XMAX 1024
X#define TEK40YMAX 780
X
X#define TEK40XLAST (TEK40XMAX - 1)
X#define TEK40YLAST (TEK40YMAX - 1)
X
X#define TEK40VCHAR 	25
X#define TEK40HCHAR		14
X#define TEK40VTIC		11
X#define TEK40HTIC		11	
X
X#define HALFTEK40XMAX 780
X#define HALFTEK40YMAX 512
X#define HALFTEK40XMID 390
X#define HALFTEK40YMID 256
X#define HALFTEK40XLAST (HALFTEK40XMAX - 1)
X#define HALFTEK40YLAST (HALFTEK40YMAX - 1)
X
X#define HALFTEK40VCHAR 	25
X#define HALFTEK40HCHAR		14
X#define HALFTEK40VTIC		11
X#define HALFTEK40HTIC		11	
X
X#ifdef UNIXPLOT
X
X#define UP_XMAX 4096
X#define UP_YMAX 4096
X
X#define UP_XLAST (UP_XMAX - 1)
X#define UP_YLAST (UP_YMAX - 1)
X
X#define UP_VCHAR (UP_YMAX/30)
X#define UP_HCHAR (UP_XMAX/72)	/* just a guess--no way to know this! */
X#define UP_VTIC (UP_YMAX/80)
X#define UP_HTIC (UP_XMAX/80)
X
X#endif /* UNIXPLOT */
X
X
X
X#define TERMCOUNT (sizeof(term_tbl)/sizeof(struct termentry))
X
X#ifdef PC
X
XPC_lrput_text(row,str)
Xint row;
Xchar str[];
X{
X	PC_curloc(24-row,78-strlen(str));
X	PC_puts(str);
X}
X
XPC_ulput_text(row,str)
Xint row;
Xchar str[];
X{
X	PC_curloc(row+1,2);
X	PC_puts(str);
X}
X
X#ifdef CORONA
XCOR_init()
X{
X}
X
XCOR_graphics()
X{
X	graphics_on = TRUE;
X	Vmode(3);
X	grinit(screen);
X	grandtx();
X}
X
XCOR_text()
X{
X	if (graphics_on) {
X		graphics_on = FALSE;
X		while (!kbhit())
X			;
X	}
X	grreset();
X	txonly();
X	Vmode(3);
X}
X
XCOR_linetype(linetype)
X{
X	if (linetype > 2)
X		linetype %= 3;
X	mask = pattern[linetype+2];
X}
X
XCOR_move(x,y)
X{
X	if (x < 0)
X		startx = 0;
X	else if (x > COR_XLAST)
X		startx = COR_XLAST;
X	else
X		startx = x;
X
X	if (y < 0)
X		starty = 0;
X	else if (y > COR_YLAST)
X		starty = COR_YLAST;
X	else
X		starty = y;
X}
X
XCOR_vector(x,y)
X{
X	if (x < 0)
X		x = 0;
X	else if (x > COR_XLAST)
X		x = COR_XLAST;
X	if (y < 0)
X		y = 0;
X	else if (y > COR_YLAST)
X		y = COR_YLAST;
X
X	Cor_line(startx,COR_YLAST-starty,x,COR_YLAST-y);
X	startx = x;
X	starty = y;
X}
X
X#define COR_lrput_text PC_lrput_text
X#define COR_ulput_text PC_ulput_text
X
XCOR_reset()
X{
X}
X#endif /* CORONA */
X
X
XCGA_init()
X{
X	PC_color(1);		/* monochrome */
X}
X
XCGA_graphics()
X{
X	graphics_on = TRUE;
X	Vmode(6);
X}
X
XCGA_text()
X{
X	if (graphics_on) {
X		graphics_on = FALSE;
X		while (!kbhit())
X			;
X		Vmode(3);
X	}
X}
X
XCGA_linetype(linetype)
X{
X	if (linetype > 2)
X		linetype %= 3;
X	PC_mask(pattern[linetype+2]);
X}
X
XCGA_move(x,y)
X{
X	startx = x;
X	starty = y;
X}
X
X
XCGA_vector(x,y)
X{
X	PC_line(startx,CGA_YLAST-starty,x,CGA_YLAST-y);
X	startx = x;
X	starty = y;
X}
X
X#define CGA_lrput_text PC_lrput_text
X#define CGA_ulput_text PC_ulput_text
X
X
XCGA_reset()
X{
X}
X
X
XEGA_init()
X{
X	PC_mask(0xffff);
X}
X
XEGA_graphics()
X{
X	graphics_on = TRUE;
X	Vmode(16);
X}
X
XEGA_text()
X{
X	PC_curloc(24,0);
X	if (graphics_on) {
X		graphics_on = FALSE;
X		while (!kbhit())
X			;
X	}
X}
X
XEGA_linetype(linetype)
X{
X	static int c[] = {9, 8, 10, 11, 12, 13, 14, 15, 7, 5, 4, 3, 2, 6};
X	PC_color(c[linetype+2]);
X}
X
XEGA_move(x,y)
X{
X	startx = x;
X	starty = y;
X}
X
X
XEGA_vector(x,y)
X{
X	PC_line(startx,EGA_YLAST-starty,x,EGA_YLAST-y);
X	startx = x;
X	starty = y;
X}
X
X#define EGA_lrput_text PC_lrput_text
X#define EGA_ulput_text PC_ulput_text
X
X
XEGA_reset()
X{
X	Vmode(3);
X}
X#endif /* PC */
X
X
X#ifdef AED
XAED_init()
X{
X	fprintf(outfile,
X	"\033SEN3DDDN.SEC.7.SCT.0.1.80.80.90.SBC.0.AAV2.MOV.0.9.CHR.0.FFD");
X/*   2            3     4                5     7    6       1
X	1. Clear Screen
X	2. Set Encoding
X	3. Set Default Color
X	4. Set Backround Color Table Entry
X	5. Set Backround Color
X	6. Move to Bottom Lefthand Corner
X	7. Anti-Alias Vectors
X*/
X}
X
X
XAED_graphics()
X{
X	fprintf(outfile,"\033FFD\033");
X}
X
X
XAED_text()
X{
X	fprintf(outfile,"\033MOV.0.9.SEC.7.XXX");
X}
X
X
X
XAED_linetype(linetype)
Xint linetype;
X{
Xstatic int color[9+2] = { 7, 1, 6, 2, 3, 5, 1, 6, 2, 3, 5 };
Xstatic int type[9+2] = { 85, 85, 255, 255, 255, 255, 255,
X					85, 85, 85, 85 };
X	
X	fprintf(outfile,"\033SLS%d.255.",type[linetype+2]);
X	fprintf(outfile,"\033SEC%d.",color[linetype+2]);
X
X}
X
X
X
XAED_move(x,y)
Xint x,y;
X{
X	fprintf(outfile,"\033MOV%d.%d.",x,y);
X}
X
X
XAED_vector(x,y)
Xint x,y;
X{
X	fprintf(outfile,"\033DVA%d.%d.",x,y);
X}
X
X
XAED_lrput_text(row,str) /* write text to screen while still in graphics mode */
Xint row;
Xchar str[];
X{
X	AED_move(AED_XMAX-((strlen(str)+2)*AED_HCHAR),AED_VTIC+AED_VCHAR*(row+1));
X	fprintf(outfile,"\033XXX%s\033",str);
X}
X
X
XAED_ulput_text(row,str) /* write text to screen while still in graphics mode */
Xint row;
Xchar str[];
X{
X	AED_move(AED_HTIC*2,AED_YMAX-AED_VTIC-AED_VCHAR*(row+1));
X	fprintf(outfile,"\033XXX%s\033",str);
X}
X
X
X#define hxt (AED_HTIC/2)
X#define hyt (AED_VTIC/2)
X
XAED_reset()
X{
X	fprintf(outfile,"\033SCT0.1.0.0.0.SBC.0.FFD");
X}
X
X#endif /* AED */
X
X
X
X
X#ifdef HP75
X
XHP75_init()
X{
X	fprintf(outfile,
X	"\033.Y;IN;\033.P1:SC0,%d,0,%d;\nRO90;IP;CS20;SI0.2137,0.2812;\n",
X		HP75_XMAX,HP75_YMAX);
X/*	 1      2  3       4             5    6  7
X	1. turn on eavesdropping
X	2. reset to power-up defaults
X	3. enable XON/XOFF flow control
X	4. set SCaling to 2000 x 2000
X	5. rotate page 90 degrees
X	6. ???
X	7. set some character set stuff
X*/
X}
X
X
XHP75_graphics()
X{
X	fputs("\033.Y",outfile);
X/*         1
X	1. enable eavesdropping
X*/
X}
X
X
XHP75_text()
X{
X	fputs("NR;\033.Z",outfile);
X/*         1  2
X	1. go into 'view' mode
X	2. disable plotter eavesdropping
X*/
X}
X
X
XHP75_linetype(linetype)
Xint linetype;
X{
X	fprintf(outfile,"SP%d;\n",3+(linetype%8));
X}
X
X
XHP75_move(x,y)
Xint x,y;
X{
X	fprintf(outfile,"PU%d,%d;\n",x,y);
X}
X
X
XHP75_vector(x,y)
Xint x,y;
X{
X	fprintf(outfile,"PD%d,%d;\n",x,y);
X}
X
X
XHP75_lrput_text(row,str)
Xint row;
Xchar str[];
X{
X	HP75_move(HP75_XMAX-HP75_HTIC*2,HP75_VTIC*2+HP75_VCHAR*row);
X	fprintf(outfile,"LO17;LB%s\003\n",str);
X}
X
XHP75_ulput_text(row,str)
Xint row;
Xchar str[];
X{
X	HP75_move(HP75_HTIC*2,HP75_YMAX-HP75_VTIC*2-HP75_VCHAR*row);
X	fprintf(outfile,"LO13;LB%s\003\n",str);
X}
X
XHP75_reset()
X{
X}
X
X#endif /* HP75 */
X
X
X
X#ifdef REGIS
X
XREGISinit()
X{
X	fprintf(outfile,"\033[r\033[24;1H");
X/*                   1     2
X	1. reset scrolling region
X	2. locate cursor on bottom line
X*/
X}
X
X
XREGISgraphics()
X{
X	fprintf(outfile,"\033[2J\033P1pS(C0)");
X/*                   1      2      3
X	1. clear screen
X	2. enter ReGIS graphics
X	3. turn off graphics diamond cursor
X*/
X}
X
X
XREGIStext()
X{
X	fprintf(outfile,"\033[24;1H");
X/*	                 1
X 	1. locate cursor on last line of screen (and leave ReGIS)
X*/
X}
X
X
XREGISlinetype(linetype)
Xint linetype;
X{
X	static int in_map[9+2] = {2,2,3,2,3,2,3,2,1,1,1};
X	static int lt_map[9+2] = {1,4,1,1,4,4,6,6,1,4,6};
X	fprintf(outfile,"W(I%d)",in_map[linetype+2]);
X	fprintf(outfile,"W(P%d)",lt_map[linetype+2]);
X}
X
X
XREGISmove(x,y)
Xint x,y;
X{
X	fprintf(outfile,"P[%d,%d]v[]",x,REGISYLAST-y,x,REGISYLAST-y);
X}
X
X
XREGISvector(x,y)
Xint x,y;
X{
X	fprintf(outfile,"v[%d,%d]",x,REGISYLAST - y);
X}
X
X
XREGISlrput_text(row,str)
Xint row;
Xchar *str;
X{
X	REGISmove(REGISXMAX-REGISHTIC-REGISHCHAR*(strlen(str)+3),
X		REGISVTIC+REGISVCHAR*(row+1));
X	(void) putc('T',outfile); (void) putc('\'',outfile);
X	while (*str) {
X		(void) putc(*str,outfile);
X		if (*str == '\'')
X				(void) putc('\'',outfile);	/* send out another one */
X		str++;
X	}
X	(void) putc('\'',outfile);
X}
X
X
XREGISulput_text(row,str)
Xint row;
Xchar *str;
X{
X	REGISmove(REGISVTIC,REGISYMAX-REGISVTIC*2-REGISVCHAR*row);
X	(void) putc('T',outfile); (void) putc('\'',outfile);
X	while (*str) {
X		(void) putc(*str,outfile);
X		if (*str == '\'')
X				(void) putc('\'',outfile);	/* send out another one */
X		str++;
X	}
X	(void) putc('\'',outfile);
X}
X
X
XREGISreset()
X{
X	fprintf(outfile,"\033[2J\033[24;1H");
X}
X
X#endif /* REGIS */
X
X
X
X
X#ifdef QMS
X
XQMS_init()
X{
X	fprintf(outfile,"^IOL\n");
X}
X
X
XQMS_graphics()
X{
X	fprintf(outfile,"^IGV\n");
X}
X
X
X
XQMS_text()
X{
X	fprintf(outfile,"^IGE\n^,");
X}
X
X
XQMS_linetype(linetype)
Xint linetype;
X{
Xstatic int width[9+2] = {7, 3, 3, 3, 3, 5, 5, 5, 7, 7, 7};
Xstatic int type[9+2] =  {0, 0, 0, 2, 5, 0, 2, 5, 0, 2, 5};
X	fprintf(outfile,"^PW%02d\n^V%x\n",width[linetype+2], type[linetype+2]);
X}
X
X
XQMS_move(x,y)
Xint x,y;
X{
X	fprintf(outfile,"^U%05d:%05d\n", 1000 + x, QMS_YLAST + 1000 - y);
X}
X
X
XQMS_vector(x2,y2)
Xint x2,y2;
X{
X	fprintf(outfile,"^D%05d:%05d\n", 1000 + x2, QMS_YLAST + 1000 - y2);
X}
X
X
XQMS_lrput_text(row,str)
Xint row;
Xchar str[];
X{
X	QMS_move(QMS_XMAX-QMS_HTIC-QMS_HCHAR*(strlen(str)+1),
X		QMS_VTIC+QMS_VCHAR*(row+1));
X	fprintf(outfile,"^IGE\n%s\n^IGV\n",str);
X}
X
XQMS_ulput_text(row,str)
Xint row;
Xchar str[];
X{
X	QMS_move(QMS_HTIC*2,QMS_YMAX-QMS_VTIC-QMS_VCHAR*(row+1));
X	fprintf(outfile,"^IGE\n%s\n^IGV\n",str);
X}
X
X
XQMS_reset()
X{
X	fprintf(outfile,"^,\n");
X}
X
X#endif /* QMS */
X
X
X
X#ifdef TEK
X
X#define HX 0x20		/* bit pattern to OR over 5-bit data */
X#define HY 0x20
X#define LX 0x40
X#define LY 0x60
X
X#define LOWER5 31
X#define UPPER5 (31<<5)
X
X
XTEK40init()
X{
X}
X
X
XTEK40graphics()
X{
X	fprintf(outfile,"\033\014");
X/*                   1
X	1. clear screen
X*/
X}
X
X
XTEK40text()
X{
X	TEK40move(0,12);
X	fprintf(outfile,"\037");
X/*                   1
X	1. into alphanumerics
X*/
X}
X
X
XTEK40linetype(linetype)
Xint linetype;
X{
X}
X
X
X
XTEK40move(x,y)
Xunsigned int x,y;
X{
X	(void) putc('\035', outfile);	/* into graphics */
X	TEK40vector(x,y);
X}
X
X
XTEK40vector(x,y)
Xunsigned int x,y;
X{
X	(void) putc((HY | (y & UPPER5)>>5), outfile);
X	(void) putc((LY | (y & LOWER5)), outfile);
X	(void) putc((HX | (x & UPPER5)>>5), outfile);
X	(void) putc((LX | (x & LOWER5)), outfile);
X}
X
X
XTEK40lrput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	TEK40move(TEK40XMAX - TEK40HTIC - TEK40HCHAR*(strlen(str)+1),
X		TEK40VTIC + TEK40VCHAR*(row+1));
X	fprintf(outfile,"\037%s\n",str);
X}
X
X
XTEK40ulput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	TEK40move(TEK40HTIC, TEK40YMAX - TEK40VTIC - TEK40VCHAR*(row+1));
X	fprintf(outfile,"\037%s\n",str);
X}
X
X
XTEK40reset()
X{
X}
X
X#endif /* TEK */
X
X#ifdef HALFTEK
X
X#define HALF_HX 0x20		/* bit pattern to OR over 5-bit data */
X#define HALF_HY 0x20
X#define HALF_LX 0x40
X#define HALF_LY 0x60
X
X#define HALF_LOWER5 31
X#define HALF_UPPER5 (31<<5)
X
X
XHALFTEK40init()
X{
X}
X
X
XHALFTEK40graphics()
X{
X	fprintf(outfile,"\033\014");
X/*                   1
X	1. clear screen
X*/
X}
X
X
XBOTTEK40text()
X{
X	BOTTEK40move(0,12);
X	fprintf(outfile,"\037");
X/*                   1
X	1. into alphanumerics
X*/
X}
X
XTOPTEK40text()
X{
X	TOPTEK40move(0,12);
X	fprintf(outfile,"\037");
X/*                   1
X	1. into alphanumerics
X*/
X}
X
X
XHALFTEK40linetype(linetype)
Xint linetype;
X{
X}
X
X
X
XTOPTEK40move(x,y)
Xunsigned int x,y;
X{
X	(void) putc('\035', outfile);	/* into graphics */
X	TOPTEK40vector(x,y);
X}
X
XBOTTEK40move(x,y)
Xunsigned int x,y;
X{
X	(void) putc('\035', outfile);	/* into graphics */
X	BOTTEK40vector(x,y);
X}
X
X
XBOTTEK40vector(x,y)
Xunsigned int x,y;
X{
X	(void) putc((HALF_HY | (x & HALF_UPPER5)>>5), outfile);
X	(void) putc((HALF_LY | (x & HALF_LOWER5)), outfile);
X	(void) putc((HALF_HX | (((HALFTEK40YLAST-y)+HALFTEK40YMAX) & HALF_UPPER5)>>5), outfile);
X	(void) putc((HALF_LX | (((HALFTEK40YLAST-y)+HALFTEK40YMAX) & HALF_LOWER5)), outfile);
X}
X
X
XTOPTEK40vector(x,y)
Xunsigned int x,y;
X{
X	(void) putc((HALF_HY | (x & HALF_UPPER5)>>5), outfile);
X	(void) putc((HALF_LY | (x & HALF_LOWER5)), outfile);
X	(void) putc((HALF_HX | (((HALFTEK40YMID-y)+HALFTEK40YMID) & HALF_UPPER5)>>5), outfile);
X	(void) putc((HALF_LX | (((HALFTEK40YMID-y)+HALFTEK40YMID) & HALF_LOWER5)), outfile);
X}
X
XHALFTEK40lrput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X}
X
X
XHALFTEK40ulput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X}
X
X
XHALFTEK40reset()
X{
X}
X
X#endif /* HALFTEK */
X
X#ifdef UNIXPLOT
XUP_init()
X{
X	openpl();
X	space(0, 0, UP_XMAX, UP_YMAX);
X}
X
X
XUP_graphics()
X{
X	erase();
X}
X
X
XUP_text()
X{
X}
X
X
XUP_linetype(linetype)
Xint linetype;
X{
Xstatic char *lt[] = {"solid", "longdashed", "solid", "dotted", "shortdashed",
X	"dotdashed", "longdashed"};
X
X	if (linetype >= 5)
X		linetype %= 5;
X	linemod(lt[linetype+2]);
X}
X
X
XUP_move(x,y)
Xunsigned int x,y;
X{
X	move(x,y);
X}
X
X
XUP_vector(x,y)
Xunsigned int x,y;
X{
X	cont(x,y);
X}
X
X
XUP_lrput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	move(UP_XMAX - UP_HTIC - UP_HCHAR*(strlen(str)+1),
X		UP_VTIC + UP_VCHAR*(row+1));
X	label(str);
X}
X
X
XUP_ulput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	UP_move(UP_HTIC, UP_YMAX - UP_VTIC - UP_VCHAR*(row+1));
X	label(str);
X}
X
XUP_reset()
X{
X	closepl();
X}
X
X#endif /* UNIXPLOT */
X
X#ifdef LATEX
X
X#define LATEX_PTS_PER_INCH (72.27)
X#define LATEX_UNIT (.01)		/* points */
X
X#define LATEX_HTIC (5./LATEX_UNIT)
X#define LATEX_VTIC (5./LATEX_UNIT)
X#define LATEX_HCHAR (4./LATEX_UNIT)
X#define LATEX_VCHAR (12./LATEX_UNIT)
X
X#define LATEX_TICSIZ 101		/* no more than 100 chars in a tic label */
X
Xstatic int LATEX_posx;
Xstatic int LATEX_posy;
Xstatic int LATEX_inplot;
Xstatic int LATEX_xmax;
Xstatic int LATEX_ymax;
Xstatic char *LATEX_xlabel = NULL;
X
Xstatic LATEX_endplot();
Xextern char *malloc();
X
X#define sign(x) ((x) >= 0 ? 1 : -1)
X#define abs(x) ((x) >= 0 ? (x) : -(x))
X#define max(a,b) ((a) > (b) ? (a) : (b))
X#define min(a,b) ((a) < (b) ? (a) : (b))
X
X/* Default line-drawing character */
X#define LATEX_DOT_SPACING (2.0/LATEX_UNIT)
X#define LATEX_DOT "\\circle*{1}"
X#define LATEX_TINY_DOT "{\\sevrm $\\cdot$}"
X
Xstatic int LATEX_type;		/* negative types use real lines */
Xstatic struct st_entry *LATEX_style = NULL; /* NULL => use default styles */
Xstatic LATEX_seq_pos;		/* position in sequence */
X
X#define LATEX_POINT_TYPES POINT_TYPES /* we use the same points */
Xstatic char *LATEX_points[] = {
X    "$\\Diamond$", "$+$", "$\\Box$", "$\\times$", "$\\triangle$", "$\\star$"
X};
X
XLATEX_init()
X{
X    LATEX_posx = LATEX_posy = 0;
X    LATEX_inplot = FALSE;
X    LATEX_style = NULL;
X    LATEX_type = -1;
X
X    fprintf(outfile, "\\setlength{\\unitlength}{%gpt}\n", LATEX_UNIT);
X}
X
X
XLATEX_graphics(xmax, ymax, t, xlabel, ylabel, yskip, title)
X	float xmax, ymax;		/* in inches */
X	struct termentry *t;
X	char *xlabel;			/* x-axis label */
X	char *ylabel;			/* y-axis label */
X	int yskip;			/* y-axis label skip factor */
X	char *title;			/* plot title */
X{
X    /* computed margin of plot */
X    int bot_margin, left_margin, top_margin, right_margin;
X
X    if (LATEX_inplot) 
X	 LATEX_endplot();
X
X    /* Convert inches to points to coordinates */
X    LATEX_xmax = (int) (xmax * LATEX_PTS_PER_INCH / LATEX_UNIT + 0.5);
X    LATEX_ymax = (int) (ymax * LATEX_PTS_PER_INCH / LATEX_UNIT + 0.5);
X
X    /* store these away for the use of plotting routines */
X    t->xmax = LATEX_xmax;
X    t->ymax = LATEX_ymax;
X
X    /* Compute the margins, based on the positioning of tick labels */
X    left_margin = LATEX_VTIC + 2*LATEX_HCHAR;
X    right_margin = 0;
X    bot_margin = LATEX_HTIC + LATEX_VCHAR;
X    top_margin = LATEX_VTIC;
X
X    /* Construct the image from the labels and the plot, as a table */
X    fprintf(outfile, "\\begin{tabular}{r@{}c}\n");
X    if (title && *title != '\0')
X	 fprintf(outfile, " & \\shortstack{%s} \\\\ \n", title);
X    if (ylabel && *ylabel != '\0') {
X	   fprintf(outfile, "\\raisebox{%gpt}{\\begin{tabular}[c]{@{}c@{}}\n", 
X			 ((float)(LATEX_ymax-1) / 2. + bot_margin) * LATEX_UNIT);
X	   fprintf(outfile, "%s\n", ylabel);
X	   fprintf(outfile, "\\end{tabular} \\hspace*{%dem}}\n", yskip);
X    }
X    /* Define the plot, computing the total size and the lower-left corner*/
X    fprintf(outfile, " & \\begin{picture}(%d,%d)(%d,%d)\n", 
X		  (int)(LATEX_xmax + left_margin + right_margin),
X		  (int)(LATEX_ymax + bot_margin + top_margin),
X		  (int)(-left_margin), (int)(-bot_margin));
X    LATEX_inplot = TRUE;
X
X    LATEX_posx = LATEX_posy = 0;
X
X    /* Remember x label for use after plot is defined */
X    if (xlabel && *xlabel != '\0') {
X	   LATEX_xlabel = malloc(strlen(xlabel)+1);
X	   strcpy(LATEX_xlabel, xlabel);
X    } else
X	 LATEX_xlabel = NULL;
X}
X
X
Xstatic 
XLATEX_endplot()
X{
X    /* Complete the plot */
X    fprintf(outfile, "\\end{picture}\n");
X
X    /* Now finish that line of the table and do the x label */
X    if (LATEX_xlabel) {
X	   fprintf(outfile, "\\\\\n");
X	   fprintf(outfile, " & \\shortstack{%s}\n", LATEX_xlabel);
X	   free(LATEX_xlabel);
X    }
X    fprintf(outfile, "\\end{tabular}\n\n");
X}
X
X
XLATEX_text()
X{
X}
X
X
XLATEX_linetype(linetype)
Xint linetype;
X{
X    LATEX_type = linetype;
X    LATEX_style = NULL;
X}
X
X
XLATEX_plotstyle(stp)
Xstruct st_entry *stp;
X{
X    LATEX_style = stp;
X    LATEX_seq_pos = 0;
X}
X
X
XLATEX_move(x,y)
Xunsigned int x,y;
X{
X    LATEX_posx = x;
X    LATEX_posy = y;
X}
X
X
XLATEX_point(x,y, number, special)		/* version of line_and_point */
Xunsigned int x,y;
Xint number;				/* type of point */
Xchar *special;				/* overrides number as the character to use */
X{
X    if (clipping && (x < LATEX_HTIC || y < LATEX_VTIC || 
X				 x >= LATEX_xmax-LATEX_HTIC ||
X				 y >= LATEX_ymax-LATEX_VTIC) ) 
X	 return;
X
X    LATEX_move(x,y);
X    
X    /* Print the special character, if given, otherwise use the one */
X    /* defined by 'number'; number < 0 means to use a dot, otherwise */
X    /* one of the defined points. */
X    fprintf(outfile, "\\put(%d,%d){\\makebox(0,0){%s}}\n", x, y, 
X		  special != NULL ? special :
X		    (number < 0 ? LATEX_TINY_DOT
X			: LATEX_points[number % LATEX_POINT_TYPES]));
X}
X
X
XLATEX_vector(ux,uy)
Xunsigned int ux,uy;
X{
X    int x=ux, y=uy;
X
X    /* Negative linestyles are straight lines for frame and axes. */
X    /* These are vertical and horizontal lines only. */
X    if (LATEX_type < 0) {
X	   if (x == LATEX_posx) {		/* vertical */
X		  fprintf(outfile, "\\put(%d,%d){\\line(0,%d){%d}}\n",
X				(int)(LATEX_posx), (int)(LATEX_posy), 
X				sign(y - LATEX_posy), abs(y - LATEX_posy));
X	   } else if (y == LATEX_posy) {		/* horizontal */
X		  fprintf(outfile, "\\put(%d,%d){\\line(%d,0){%d}}\n",
X				LATEX_posx, LATEX_posy, 
X				sign(x - LATEX_posx), abs(x - LATEX_posx));
X	   }
X    } else {				/* drawing real curves */
X	   int deltax = x - LATEX_posx;
X	   int deltay = y - LATEX_posy;
X	   int n = max(abs(deltax), abs(deltay)) 
X		/ (LATEX_style ? LATEX_style->st_spacing/LATEX_UNIT : LATEX_DOT_SPACING) + 1;
X	   float dx = (float)deltax / n;
X	   float dy = (float)deltay / n;
X	   float curx = LATEX_posx, cury = LATEX_posy;
X	   int first = TRUE;
X
X	   while (curx != x || cury != y) {
X		  if (LATEX_style)
X		    if (!first)
X			 LATEX_seq_pos = (LATEX_seq_pos + 1) % LATEX_style->st_length;
X		    else
X			 first = FALSE;
X
X		  fprintf(outfile, "\\put(%d,%d){%s}\n", 
X				(int)(curx + .5), (int)(cury + .5), 
X				LATEX_style ? LATEX_style->st_seq[LATEX_seq_pos]
X				            : LATEX_DOT);
X
X		  if (abs(dx) > abs(x - curx))
X		    curx = x;
X		  else
X		    curx += dx;
X
X		  if (abs(dy) > abs(y - cury))
X		    cury = y;
X		  else
X		    cury += dy;
X	   }
X    }
X
X    LATEX_posx = x;
X    LATEX_posy = y;
X}
X
XLATEX_lrput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	fprintf(outfile, "\\put(%d,%d){$%s$}\n",
X		   (int)(LATEX_xmax - 2*LATEX_HTIC - LATEX_HCHAR*(strlen(str)+1)),
X		   (int)(LATEX_VTIC + 3 + LATEX_VCHAR*row),
X		   str);
X}
X
X
XLATEX_ulput_text(row,str)
Xunsigned int row;
Xchar str[];
X{
X	fprintf(outfile, "\\put(%d,%d){%s}\n",
X		   (int)(LATEX_HTIC+3),
X		   (int)(LATEX_ymax - LATEX_VTIC - LATEX_VCHAR*(row+1)),
X		   str);
X}
X
XLATEX_xyput_text(x, y, str, pos, length, dx, dy)
Xunsigned int x,y;			/* reference point of string */
Xchar str[];				/* the text */
Xchar pos[];				/* for optional [pos] to \makebox */
Xunsigned int length;		/* optional arrow length */
Xint dx, dy;				/* optional slopes for arrow */
X{
X    if (!LATEX_inplot)
X	 return;
X
X    if (pos != NULL && *pos != NULL) {
X	   fprintf(outfile, "\\put(%d,%d){\\makebox(0,0)[%s]{%s}",
X			 x, y, pos, str);
X    } else {
X	   fprintf(outfile, "\\put(%d,%d){\\makebox(0,0){%s}",
X			 x, y, str);
X    }
X
X    /* optional arrow */
X    if (length != 0 && pos != NULL && *pos != NULL) {
X	   if (dx == 0 && dy == 0) { /* determine slope from pos */
X		  if (index(pos, 'l')) dx = -1;
X		  if (index(pos, 'r')) dx = 1;
X		  if (index(pos, 't')) dy = 1;
X		  if (index(pos, 'b')) dy = -1;
X	   }
X	   fprintf(outfile, "\\vector(%d,%d){%u}\n", dx, dy, length);
X    }
X
X    fprintf(outfile, "}\n");	/* finish the \put */
X}
X
XLATEX_key(x, y, style, names)
X	unsigned int x,y;
X	int style[];
X	char *names[];
X{
X    int entry;
X    int pcount = 0;			/* counter of point-like styles */
X    char *point;			/* string representing type */
X    static char *LATEX_key_point();
X    int first = 1;			/* (TRUE) */
X
X    /* Plot all of the entries in a shortstack */
X    /* Each entry has two boxes, the left right-justified,  */
X    /* the right left-justified, so they line up at the middle. */
X    fprintf(outfile, "\\put(%d,%d){\\shortstack{\n", x, y);
X    for (entry = 0; names[entry] != NULL; entry++) {
X	   /* Get a string that describes this style */
X	   point = LATEX_key_point(style[entry], &pcount);
X
X	   /* But don't print it out if the description is empty */
X	   if (*names[entry] != '\0') {
X		  if (!first) 
X		    fprintf(outfile, "\\\\\n");
X		  else
X		    first = FALSE;
X		  fprintf(outfile, " \\makebox[0pt][r]{%s}", point);
X		  fprintf(outfile, " \\makebox[0pt][l]{ %s}", names[entry]);
X	   }
X    }
X    fprintf(outfile, "\n}}\n");
X}
X
Xstatic 
Xchar *					/* pointer to static storage */
XLATEX_key_point(style, pcount)
X	int style;			/* style number to describe */
X	int *pcount;			/* running counter of point-like styles */
X{
X    static char s[MAX_ID_LEN]; /* the string representing the style */
X    struct st_entry *stp;	/* the style description of this style */
X    int seq;				/* sequence in a style */
X    int p;				/* loop variable */
X    extern struct st_entry st[]; /* all style descriptions */
X
X    switch(style) {
X	   case IMPULSES: {
X		  strcpy(s, "|"); /* hack */
X		  break;
X	   }
X	   case LINES: {
X		  *s = NULL;
X		  for (p=0; p < 5; p++)
X		    sprintf(s, "%s%s\\hspace{%gpt}", 
X				  s, LATEX_DOT, LATEX_DOT_SPACING * LATEX_UNIT);
X		  break;
X	   }
X	   case POINTS: {	/* hack */
X		  strcpy(s, LATEX_points[(*pcount)++ % LATEX_POINT_TYPES]);
X		  break;
X	   }
X	   case DOTS: {
X		  strcpy(s, LATEX_TINY_DOT);
X		  break;
X	   }
X	   case LINESPOINTS: {
X		  *s = NULL;
X		  for (p=0; p < 5; p++) {
X			 sprintf(s, "%s%s\\hspace{%gpt}", 
X				    s, LATEX_DOT, LATEX_DOT_SPACING * LATEX_UNIT);
X			 if (p == 2)
X			   strcat(s, LATEX_points[(*pcount)++ % LATEX_POINT_TYPES]);
X		  }
X		  break;
X	   }
X	   default: {
X		  *s = NULL;
X		  /* Plot points if the style has a line pattern */
X		  stp = &(st[style]);
X		  if (stp->st_length > 0) {
X			 for (p=0, seq=0; p < 5; p++) {
X				sprintf(s, "%s%s\\hspace{%gpt}", 
X					   s, stp->st_seq[seq], stp->st_spacing); 
X				seq = (seq + 1) % stp->st_length;
X				if (p == 2 && stp->st_point != NULL) 
X				  strcat(s, stp->st_point);
X			 }
X		  } else {		  
X			 /* and plot the data point if the style has that */
X			 if (stp->st_point != NULL) 
X			   strcat(s, stp->st_point);
X		  }
X		  break;
X	   }
X    }
X
X    return (s);
X}
X
XLATEX_xtick_text(x, number, format)
Xunsigned int x;			/* place to put on axis */
Xdouble number;				/* the number to be written at that tick */
Xchar *format;
X{
X    char mark[LATEX_TICSIZ];
X
X    sprintf(mark, format, number);
X    fprintf(outfile, "\\put(%d,%d){\\makebox(0,0)[t]{%s}}\n",
X		  x, (int)(-LATEX_HTIC), mark);
X}
X
XLATEX_ytick_text(y, number, format)
Xunsigned int y;			/* place to put on axis */
Xdouble number;				/* the number to be written at that tick */
Xchar *format;
X{
X    char mark[LATEX_TICSIZ];
X
X    sprintf(mark, format, number);
X    fprintf(outfile, "\\put(%d,%d){\\makebox(0,0)[r]{%s}}\n",
X		  (int)(-LATEX_VTIC), y, mark);
X}
X
X
XLATEX_reset()
X{
X    if (LATEX_inplot) {
X	   LATEX_endplot();
X	   LATEX_inplot = FALSE;
X    }
X    LATEX_posx = LATEX_posy = 0;
X}
X
X#endif /* LATEX */
X
X
XUNKNOWN_null()
X{
X	int_error("you must set your terminal type before plotting!",NO_CARET);
X}
X
XALL_nop()					/* i.e. doesn't support this feature */
X{
X}
X
X
X/*
X * term_tbl[] contains an entry for each terminal.  "unknown" must be the
X *   first, since term is initialized to 0.
X */
Xstruct termentry term_tbl[] = {
X	{"unknown", 100, 100, 1, 1, 1, 1, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null,
X	UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null,
X	UNKNOWN_null, UNKNOWN_null,
X	UNKNOWN_null, UNKNOWN_null, UNKNOWN_null}
X#ifdef PC
X	,{"cga", CGA_XMAX, CGA_YMAX, CGA_VCHAR, CGA_HCHAR,
X		CGA_VTIC, CGA_HTIC, CGA_init, CGA_reset,
X		CGA_text, CGA_graphics, CGA_move, CGA_vector,
X		CGA_linetype, CGA_lrput_text, CGA_ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X	,{"ega", EGA_XMAX, EGA_YMAX, EGA_VCHAR, EGA_HCHAR,
X		EGA_VTIC, EGA_HTIC, EGA_init, EGA_reset,
X		EGA_text, EGA_graphics, EGA_move, EGA_vector,
X		EGA_linetype, EGA_lrput_text, EGA_ulput_text, do_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X
X#ifdef CORONA
X	,{"corona", COR_XMAX, COR_YMAX, COR_VCHAR, COR_HCHAR,
X		COR_VTIC, COR_HTIC, COR_init, COR_reset,
X		COR_text, COR_graphics, COR_move, COR_vector,
X		COR_linetype, COR_lrput_text, COR_ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif /* CORONA */
X#endif /* PC */
X
X#ifdef AED
X	,{"aed767", AED_XMAX, AED_YMAX, AED_VCHAR, AED_HCHAR,
X		AED_VTIC, AED_HTIC, AED_init, AED_reset, 
X		AED_text, AED_graphics, AED_move, AED_vector, 
X		AED_linetype, AED_lrput_text, AED_ulput_text, do_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef HP75
X	,{"hp75xx",HP75_XMAX,HP75_YMAX, HP75_VCHAR, HP75_HCHAR,HP75_VTIC,HP75_HTIC,
X		HP75_init,HP75_reset,HP75_text, HP75_graphics, HP75_move, HP75_vector,
X		HP75_linetype, HP75_lrput_text, HP75_ulput_text, do_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef QMS
X	,{"qms",QMS_XMAX,QMS_YMAX, QMS_VCHAR, QMS_HCHAR, QMS_VTIC, QMS_HTIC,
X		QMS_init,QMS_reset, QMS_text, QMS_graphics, QMS_move, QMS_vector,
X		QMS_linetype,QMS_lrput_text,QMS_ulput_text,line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef REGIS
X	,{"regis", REGISXMAX, REGISYMAX, REGISVCHAR, REGISHCHAR, REGISVTIC,
X		REGISHTIC, REGISinit, REGISreset, REGIStext, REGISgraphics,
X		REGISmove,REGISvector,REGISlinetype, REGISlrput_text, REGISulput_text,
X		line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef TEK
X	,{"tek40xx",TEK40XMAX,TEK40YMAX,TEK40VCHAR, TEK40HCHAR, TEK40VTIC, 
X		TEK40HTIC, TEK40init,TEK40reset, TEK40text, TEK40graphics, 
X		TEK40move, TEK40vector,TEK40linetype,TEK40lrput_text,
X		TEK40ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef HALFTEK
X	,{"toptek",HALFTEK40XMAX,HALFTEK40YMAX,HALFTEK40VCHAR, HALFTEK40HCHAR, HALFTEK40VTIC, 
X		HALFTEK40HTIC, HALFTEK40init,HALFTEK40reset, TOPTEK40text, HALFTEK40graphics, 
X		TOPTEK40move, TOPTEK40vector,HALFTEK40linetype,HALFTEK40lrput_text,
X		HALFTEK40ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X	,{"bottek",HALFTEK40XMAX,HALFTEK40YMAX,HALFTEK40VCHAR, HALFTEK40HCHAR, HALFTEK40VTIC, 
X		HALFTEK40HTIC, HALFTEK40init,HALFTEK40reset, BOTTEK40text, HALFTEK40graphics, 
X		BOTTEK40move, BOTTEK40vector,HALFTEK40linetype,HALFTEK40lrput_text,
X		HALFTEK40ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef UNIXPLOT
X	,{"unixplot", UP_XMAX, UP_YMAX, UP_VCHAR, UP_HCHAR, UP_VTIC, UP_HTIC,
X		UP_init, UP_reset, UP_text, UP_graphics, UP_move, UP_vector,
X		UP_linetype, UP_lrput_text, UP_ulput_text, line_and_point,
X	     ALL_nop, ALL_nop, ALL_nop, ALL_nop}
X#endif
X
X#ifdef LATEX
X	/* xmax and ymax are filled in by LATEX_graphics */
X	/* We supply the absolute maximum here */
X	,{"latex", 8.5*LATEX_PTS_PER_INCH, 11*LATEX_PTS_PER_INCH,
X	    LATEX_VCHAR, LATEX_HCHAR, LATEX_VTIC, LATEX_HTIC,
X	    LATEX_init, LATEX_reset, LATEX_text, LATEX_graphics, LATEX_move, 
X	    LATEX_vector,
X	    LATEX_linetype, LATEX_lrput_text, LATEX_ulput_text, LATEX_point,
X	    LATEX_xyput_text, LATEX_xtick_text, LATEX_ytick_text, LATEX_plotstyle}
X#endif
X	};
X
X
Xlist_terms()
X{
Xregister int i;
X
X	(void) putc('\n',stderr);
X	fprintf(stderr,"available terminal types: \n");
X	for (i = 0; i < TERMCOUNT; i++)
X		fprintf(stderr,"\t%s\n",term_tbl[i].name);
X	(void) putc('\n',stderr);
X}
X
X
Xset_term(c_token)
Xint c_token;
X{
Xregister int i,t;
X
X	if (!token[c_token].is_token)
X		int_error("terminal name expected",c_token);
X	t = -1;
X	for (i = 0; i < TERMCOUNT; i++) {
X		if (!strncmp(input_line + token[c_token].start_index,term_tbl[i].name,
X			token[c_token].length)) {
X			if (t != -1)
X				int_error("ambiguous terminal name",c_token);
X			t = i;
X		}
X	}
X	if (t == -1)
X		int_error("unknown terminal type; type just 'set terminal' for a list",
X			c_token);
X	term_init = FALSE;
X	return(t);
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'util.c'
then
	echo shar: will not over-write existing file "'util.c'"
else
sed 's/^X//' << \SHAR_EOF > 'util.c'
X/*
X *
X *    G N U P L O T  --  util.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#include <ctype.h>
X#include <setjmp.h>
X#include <stdio.h>
X#include <errno.h>
X#include "plot.h"
X
Xextern BOOLEAN screen_ok;
X	/* TRUE if command just typed; becomes FALSE whenever we
X		send some other output to screen.  If FALSE, the command line
X		will be echoed to the screen before the ^ error message. */
X
X#ifndef vms
Xextern int errno, sys_nerr;
Xextern char *sys_errlist[];
X#endif /* vms */
X
Xextern char input_line[MAX_LINE_LEN];
Xextern struct lexical_unit token[MAX_TOKENS];
Xextern jmp_buf env;	/* from plot.c */
X
X
X/*
X * equals() compares string value of token number t_num with str[], and
X *   returns TRUE if they are identical.
X */
Xequals(t_num, str)
Xint t_num;
Xchar *str;
X{
Xregister int i;
X
X	if (!token[t_num].is_token)
X		return(FALSE);				/* must be a value--can't be equal */
X	for (i = 0; i < token[t_num].length; i++) {
X		if (input_line[token[t_num].start_index+i] != str[i])
X			return(FALSE);
X		}
X	/* now return TRUE if at end of str[], FALSE if not */
X	return(str[i] == '\0');
X}
X
X
X
X/*
X * almost_equals() compares string value of token number t_num with str[], and
X *   returns TRUE if they are identical up to the first $ in str[].
X */
Xalmost_equals(t_num, str)
Xint t_num;
Xchar *str;
X{
Xregister int i;
Xregister int after = 0;
Xregister start = token[t_num].start_index;
Xregister length = token[t_num].length;
X
X	if (!token[t_num].is_token)
X		return(FALSE);				/* must be a value--can't be equal */
X	for (i = 0; i < length + after; i++) {
X		if (str[i] != input_line[start + i]) {
X			if (str[i] != '$')
X				return(FALSE);
X			else {
X				after = 1;
X				start--;	/* back up token ptr */
X				}
X			}
X		}
X
X	/* i now beyond end of token string */
X
X	return(after || str[i] == '$' || str[i] == '\0');
X}
X
X
X
Xisstring(t_num)
Xint t_num;
X{
X	
X	return(token[t_num].is_token &&
X		   (input_line[token[t_num].start_index] == '\'' ||
X		   input_line[token[t_num].start_index] == '\"'));
X}
X
X
Xisnumber(t_num)
Xint t_num;
X{
X	return(!token[t_num].is_token);
X}
X
X
Xisletter(t_num)
Xint t_num;
X{
X	return(token[t_num].is_token &&
X			(isalpha(input_line[token[t_num].start_index])));
X}
X
X
X/*
X * is_definition() returns TRUE if the next tokens are of the form
X *   identifier =
X *		-or-
X *   identifier ( identifer ) =
X */
Xis_definition(t_num)
Xint t_num;
X{
X	return (isletter(t_num) &&
X			(equals(t_num+1,"=") ||			/* variable */
X			(equals(t_num+1,"(") &&		/* function */
X			 isletter(t_num+2)   &&
X			 equals(t_num+3,")") &&
X			 equals(t_num+4,"=") )
X		));
X}
X
X
X
X/*
X * copy_str() copies the string in token number t_num into str, appending
X *   a null.  No more than MAX_ID_LEN chars are copied.
X */
Xcopy_str(str, t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i = 0;
Xregister int start = token[t_num].start_index;
Xregister int count;
X
X	if ((count = token[t_num].length) > MAX_ID_LEN)
X		count = MAX_ID_LEN;
X	do {
X		str[i++] = input_line[start++];
X		} while (i != count);
X	str[i] = '\0';
X}
X
X
X/*
X * quote_str() does the same thing as copy_str, except it ignores the
X *   quotes at both ends.  This seems redundant, but is done for 
X *   efficency.
X */
Xquote_str(str, t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i = 0;
Xregister int start = token[t_num].start_index + 1;
Xregister int count;
X
X	if ((count = token[t_num].length - 2) > MAX_ID_LEN)
X		count = MAX_ID_LEN;
X    while (i != count) {
X		str[i++] = input_line[start++];
X	 }
X	str[i] = '\0';
X}
X
X/*
X *	capture() returns in str[] the the part of input_line[] which lies
X *	between the begining of token[start] and end of token[end]
X */
Xcapture(str,start,end)
Xchar str[];
Xint start,end;
X{
Xregister int i,j;
Xchar *s = str;
X
X	j = token[end].start_index + token[end].length;
X	for (i = token[start].start_index; i < j && input_line[i] != '\0'; i++)
X		*s++ = input_line[i];
X	*s = '\0';
X}
X
X
Xconvert(val_ptr, t_num)
Xstruct value *val_ptr;
Xint t_num;
X{
X	*val_ptr = token[t_num].l_val;
X}
X
X
X
Xshow_value(fp,val)
XFILE *fp;
Xstruct value *val;
X{
X		switch(val->type) {
X			case INT:
X				fprintf(fp,"%d",val->v.int_val);
X				break;
X			case CMPLX:
X				if (val->v.cmplx_val.imag != 0.0 )
X					fprintf(fp,"{%g, %g}",
X						val->v.cmplx_val.real,val->v.cmplx_val.imag);
X				else
X					fprintf(fp,"%g", val->v.cmplx_val.real);
X				break;
X			default:
X				int_error("unknown type in show_value()",NO_CARET);
X		}
X}
X
X
Xdouble
Xreal(val)		/* returns the real part of val */
Xstruct value *val;
X{
X	switch(val->type) {
X		case INT:
X			return((double) val->v.int_val);
X			break;
X		case CMPLX:
X			return(val->v.cmplx_val.real);
X	}
X	int_error("unknown type in real()",NO_CARET);
X	/* NOTREACHED */
X}
X
X
Xdouble
Ximag(val)		/* returns the imag part of val */
Xstruct value *val;
X{
X	switch(val->type) {
X		case INT:
X			return(0.0);
X			break;
X		case CMPLX:
X			return(val->v.cmplx_val.imag);
X	}
X	int_error("unknown type in real()",NO_CARET);
X	/* NOTREACHED */
X}
X
X
X
Xdouble
Xmagnitude(val)		/* returns the magnitude of val */
Xstruct value *val;
X{
X	double sqrt();
X
X	switch(val->type) {
X		case INT:
X			return((double) abs(val->v.int_val));
X			break;
X		case CMPLX:
X			return(sqrt(val->v.cmplx_val.real*
X				    val->v.cmplx_val.real +
X				    val->v.cmplx_val.imag*
X				    val->v.cmplx_val.imag));
X	}
X	int_error("unknown type in magnitude()",NO_CARET);
X	/* NOTREACHED */
X}
X
X
X
Xdouble
Xangle(val)		/* returns the angle of val */
Xstruct value *val;
X{
X	double atan2();
X
X	switch(val->type) {
X		case INT:
X			return((val->v.int_val > 0) ? 0.0 : Pi);
X			break;
X		case CMPLX:
X			if (val->v.cmplx_val.imag == 0.0) {
X				if (val->v.cmplx_val.real >= 0.0)
X					return(0.0);
X				else
X					return(Pi);
X			}
X			return(atan2(val->v.cmplx_val.imag,
X				     val->v.cmplx_val.real));
X	}
X	int_error("unknown type in angle()",NO_CARET);
X	/* NOTREACHED */
X}
X
X
Xstruct value *
Xcomplex(a,realpart,imagpart)
Xstruct value *a;
Xdouble realpart, imagpart;
X{
X	a->type = CMPLX;
X	a->v.cmplx_val.real = realpart;
X	a->v.cmplx_val.imag = imagpart;
X	return(a);
X}
X
X
Xstruct value *
Xinteger(a,i)
Xstruct value *a;
Xint i;
X{
X	a->type = INT;
X	a->v.int_val = i;
X	return(a);
X}
X
X
X
Xos_error(str,t_num)
Xchar str[];
Xint t_num;
X{
X#ifdef vms
Xstatic status[2] = {1, 0};		/* 1 is count of error msgs */
X#endif
X
Xregister int i;
X
X	/* reprint line if screen has been written to */
X
X	if (t_num != NO_CARET) {		/* put caret under error */
X		if (!screen_ok)
X			fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
X
X		for (i = 0; i < sizeof(PROMPT) - 1; i++)
X			(void) putc(' ',stderr);
X		for (i = 0; i < token[t_num].start_index; i++) {
X			(void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
X			}
X		(void) putc('^',stderr);
X		(void) putc('\n',stderr);
X	}
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X	fprintf(stderr,"%s\n",str);
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X#ifdef vms
X	status[1] = vaxc$errno;
X	sys$putmsg(status);
X	(void) putc('\n',stderr);
X#else
X	if (errno >= sys_nerr)
X		fprintf(stderr, "unknown errno %d\n\n", errno);
X	else
X		fprintf(stderr,"(%s)\n\n",sys_errlist[errno]);
X#endif
X
X	longjmp(env, TRUE);	/* bail out to command line */
X}
X
X
Xint_error(str,t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i;
X
X	/* reprint line if screen has been written to */
X
X	if (t_num != NO_CARET) {		/* put caret under error */
X		if (!screen_ok)
X			fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
X
X		for (i = 0; i < sizeof(PROMPT) - 1; i++)
X			(void) putc(' ',stderr);
X		for (i = 0; i < token[t_num].start_index; i++) {
X			(void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
X			}
X		(void) putc('^',stderr);
X		(void) putc('\n',stderr);
X	}
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X	fprintf(stderr,"%s\n\n",str);
X
X	longjmp(env, TRUE);	/* bail out to command line */
X}
SHAR_EOF
fi # end of overwriting check
if test -f 'version.c'
then
	echo shar: will not over-write existing file "'version.c'"
else
sed 's/^X//' << \SHAR_EOF > 'version.c'
Xchar version[] = "1.0.3 + latex mods 1.3";
Xchar date[] = "Mon Dec  5 13:22:46 EST 1988";
SHAR_EOF
fi # end of overwriting check
if test -f 'vmshelp.csh'
then
	echo shar: will not over-write existing file "'vmshelp.csh'"
else
sed 's/^X//' << \SHAR_EOF > 'vmshelp.csh'
X#! /bin/csh
X#
X# vmshelp.csh /usr/help/gnuplot/* > gnuplot.hlp
X# will convert the Unix help tree to VMS format,
X# then use $ LIB/HELP GNUPLOT GNUPLOT under VMS to create the VMS .HLB
X
Xif (! $?level) then
X	setenv level 0
Xendif
X@ leveltmp = ($level + 1)
Xsetenv level $leveltmp
X
Xforeach i ($*)
X	if (-f $i) then
X# plain file
X		echo -n "$level "
X		basename $i .HLP
X		sed 's/^/ /' $i
X	else if (-d $i) then
X# directory
X		echo -n "$level "
X		basename $i
X		sed 's/^/ /' $i/.HLP
X# recurse!
X		$0 $i/*
X	endif
Xend
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