GNUPLOT (1 of 4)

Thomas Williams taw at vu-vlsi.UUCP
Tue Nov 18 10:32:56 AEST 1986


	This is part 1 of 4 gnuplot shar files.

---------------------------CUT HERE-------------------------------
#! /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:
#	command.c
#	eval.c
#	graphics.c
#	internal.c
#	misc.c
# This archive created: Mon Nov 17 19:30:35 1986
export PATH; PATH=/bin:$PATH
echo shar: extracting "'command.c'" '(21464 characters)'
if test -f 'command.c'
then
	echo shar: will not over-write existing file "'command.c'"
else
cat << \SHAR_EOF > 'command.c'
/*
 *
 *    G N U P L O T  --  command.c
 *
 *  Copyright (C) 1986 Thomas Williams, Colin Kelley
 *
 *  You may use this code as you wish if credit is given and this message
 *  is retained.
 *
 *  Please e-mail any useful additions to vu-vlsi!plot so they may be
 *  included in later releases.
 *
 *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
 */

#include <stdio.h>
#include <math.h>
#include "plot.h"

#ifndef STDOUT
#define STDOUT 1
#endif

/*
 * global variables to hold status of 'set' options
 *
 */
BOOLEAN			autoscale	= TRUE;
enum PLOT_STYLE data_style	= POINTS,
				func_style	= LINES;
BOOLEAN			log_x		= FALSE,
				log_y		= FALSE;
FILE*			outfile;
char			outstr[MAX_ID_LEN+1] = "STDOUT";
int				samples		= SAMPLES;
int				term		= 0;				/* unknown term is 0 */
double			xmin		= -10,
				xmax		= 10,
				ymin		= -10,
				ymax		= 10;
double			zero = ZERO;			/* zero threshold, not 0! */


BOOLEAN screen_ok;
BOOLEAN term_init;
BOOLEAN undefined;

/*
 * instead of <strings.h>
 */

char *gets(),*getenv();
char *strcpy(),*strcat();

double magnitude(),angle(),real(),imag();
struct value *const_express(), *pop(), *complex();


extern struct vt_entry vt[];
extern struct udft_entry udft[];
extern struct termentry term_tbl[];

char input_line[MAX_LINE_LEN],dummy_var[MAX_ID_LEN + 1];
struct at_type *curr_at;
int c_token;
int next_value = (int)NEXT_VALUE,next_function = 0,c_function = 0;
int num_tokens;

struct curve_points plot[MAX_PLOTS];

static char help[80] = HELP;

#ifdef MSDOS
#include <process.h>
#endif /* MSDOS */

#ifdef vms
#include <descrip.h>
#include <rmsdef.h>
#include <errno.h>

extern lib$get_input(), lib$put_output();

int vms_len;

unsigned int status[2] = {1, 0};

$DESCRIPTOR(prompt_desc,PROMPT);
$DESCRIPTOR(line_desc,input_line);
$DESCRIPTOR(null_desc,"");

$DESCRIPTOR(help_desc,help);
$DESCRIPTOR(helpfile_desc,"GNUPLOT$HELP");

struct dsc$descriptor_s *cmd_ptr;

#endif

com_line()
{
#ifdef vms

	switch(status[1] = lib$get_input(&line_desc, &prompt_desc, &vms_len)){
		case RMS$_EOF:
			done(IO_SUCCESS);	/* ^Z isn't really an error */
			break;
		case RMS$_TNS:			/* didn't press return in time */
			vms_len--;		/* skip the last character */
			break;			/* and parse anyway */
		case RMS$_BES:			/* Bad Escape Sequence */
		case RMS$_PES:			/* Partial Escape Sequence */
			sys$putmsg(status);
			vms_len = 0;		/* ignore the line */
			break;
		case SS$_NORMAL:
			break;			/* everything's fine */
		default:
			done(status[1]);	/* give the error message */
	}

	if (vms_len && (input_line[0] == '!' || input_line[0] == '$')) {
		if (vms_len == 1)	/* spawn an interactive shell */
			cmd_ptr = &null_desc;
		else {
			cmd_ptr = &line_desc;
			input_line[0] = ' ';	/* an embarrassment, but... */
		}

		if ((status[1] = lib$spawn(cmd_ptr)) != SS$_NORMAL) {
			sys$putmsg(status);
		}
		(void) putchar('\n');

	} else {
		input_line[vms_len] = '\0';

#else
		/* not VMS */
	fprintf(stderr,PROMPT);
#ifdef MSDOS
	input_line[0] = MAX_LINE_LEN - 2;
	cgets(input_line);			/* console input so CED will work */
	(void) putc('\n',stderr);
	if (input_line[2] == 26) {
		(void) putc('\n',stderr);		/* end-of-file */
		done(IO_SUCCESS);
	}
	{
		register int i = -1;
		do				/* yuck!  move everything down two characters */
			i++;
		while (input_line[i] = input_line[i+2]);
	}

#else /* MSDOS */
		/* plain old Unix */
	if (!(int) gets(input_line)) {
		(void) putc('\n',stderr);		/* end-of-file */
		done(IO_SUCCESS);
	}
#endif /* MSDOS */

	screen_ok = TRUE; /* so we can flag any new output */

	if (input_line[0] == '!') {
		if (system(input_line + 1))
			os_error("system() failed",NO_CARET);
	} else {
#endif /* vms */
		do_line();
	}
}



do_line()  /* also used in load_file */
{
	num_tokens = scanner(input_line);
	c_token = 0;
	while(c_token < num_tokens) {
		command();
		if (c_token < num_tokens)	/* something after command */
			if (equals(c_token,";"))
				c_token++;
			else
				int_error("';' expected",c_token);
	}
}



command()
{
register int tsamp,len;
register FILE *f;
struct value a;
static char sv_file[MAX_ID_LEN+1];
			/* string holding name of save or load file */

	dummy_var[0] = '\0';		/* no dummy variable */

	if (is_definition(c_token))
		define();
	else if (equals(c_token,"help") || equals(c_token,"?")) {
		c_token++;
		len = sizeof(HELP)-1;
		help[len] = '\0';		/* remove previous help arguments */
		while (!(END_OF_COMMAND)) {
			help[len] = ' ';   /* put blank between help segments */
			copy_str(help+len+1,c_token++);
			len = strlen(help);
		}
#ifdef vms
		help_desc.dsc$w_length = len;
		if ((vaxc$errno = lbr$output_help(lib$put_output,0,&help_desc,
			&helpfile_desc,0,lib$get_input)) != SS$_NORMAL)
				os_error("can't open GNUPLOT$HELP");
#else /* vms */
		if (system(help))
			os_error("can't spawn help");
#endif /* vms */
		screen_ok = FALSE;
		c_token++;
	}
	else if (almost_equals(c_token,"pr$int")) {
		c_token++;
		(void) const_express(&a);
		(void) putc('\t',stderr);
		show_value(stderr,&a);
		(void) putc('\n',stderr);
		screen_ok = FALSE;
	}
	else if (almost_equals(c_token,"p$lot")) {
		c_token++;
		plotrequest();
	}
	else if (almost_equals(c_token,"se$t")) {
		if (almost_equals(++c_token,"t$erminal")) {
			c_token++;
			if (END_OF_COMMAND)
				list_terms();
			else
				term = set_term(c_token);
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"sa$mples")) {
			c_token++;
			tsamp = (int)magnitude(const_express(&a));
			if (tsamp < 1) 
				int_error("sampling rate must be > 0; sampling unchanged",
					c_token);
			else {
				samples = tsamp;		
				pointmem(samples);
			}
		}
		else if (almost_equals(c_token,"o$utput")) {
			c_token++;
			if (END_OF_COMMAND) {	/* no file specified */
				(void) fclose(outfile);
				outfile = fdopen(dup(STDOUT), "w");
				term_init = FALSE;
				(void) strcpy(outstr,"STDOUT");
			} else if (!isstring(c_token)) 
				int_error("expecting filename",c_token);
			else {
				quote_str(sv_file,c_token);
				if (!(f = fopen(sv_file,"w"))) {
				  os_error("cannot open file; output not changed",c_token);
				}
				(void) fclose(outfile);
				outfile = f;
				term_init = FALSE;
				outstr[0] = '\'';
				strcat(strcpy(outstr+1,sv_file),"'");
			} 
			c_token++;
		}
		else if (almost_equals(c_token,"a$utoscale")) {
			autoscale = TRUE;
			c_token++;
		} 
		else if (almost_equals(c_token,"noa$utoscale")) {
			autoscale = FALSE;
			c_token++;
		} 
		else if (almost_equals(c_token,"nol$ogscale")) {
			log_x = log_y = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"z$ero")) {
			c_token++;
			zero = magnitude(const_express(&a)); 
		}
		else if (almost_equals(c_token,"x$range")) {
			c_token++;
			if (!equals(c_token,"["))
				int_error("expecting '['",c_token);
			c_token++;
			load_range(&xmin,&xmax);
			if (!equals(c_token,"]"))
				int_error("expecting ']'",c_token);
			c_token++;
		}
		else if (almost_equals(c_token,"y$range")) {
			c_token++;
			if (!equals(c_token,"["))
				int_error("expecting '['",c_token);
			c_token++;
			load_range(&ymin,&ymax);
			autoscale = FALSE;
			if (!equals(c_token,"]"))
				int_error("expecting ']'",c_token);
			c_token++;
		}
		else if (almost_equals(c_token,"l$ogscale")) {
			c_token++;
			if (equals(c_token,"x")) {
				log_y = FALSE;
				log_x = TRUE;
				c_token++;
			}
			else if (equals(c_token,"y")) {
				log_x = FALSE;
				log_y = TRUE;
				c_token++;
			}
			else if (equals(c_token,"xy") || equals(c_token,"yx")) {
				log_x = log_y = TRUE;
				c_token++;
			}
			else
				int_error("expecting 'x', 'y', or 'xy'",c_token);
		}
		else if (almost_equals(c_token,"d$ata")) {
			c_token++;
			if (!almost_equals(c_token,"s$tyle")) 
				int_error("expecting keyword 'style'",c_token);
			c_token++;
			if (almost_equals(c_token,"l$ines")) {
				data_style = LINES;
			}
			else if (almost_equals(c_token,"i$mpulses")) {
				data_style = IMPULSES;
			}
			else if (almost_equals(c_token,"p$oints")) {
				data_style = POINTS;
			}
			else 
				int_error("expecting 'lines', 'points', or 'impulses'",c_token);
			c_token++;
		}
		else if (almost_equals(c_token,"f$unction")) {
			c_token++;
			if (!almost_equals(c_token,"s$tyle")) 
				int_error("expecting keyword 'style'",c_token);
			c_token++;
			if (almost_equals(c_token,"l$ines")) {
				func_style = LINES;
			}
			else if (almost_equals(c_token,"i$mpulses")) {
				func_style = IMPULSES;
			}
			else if (almost_equals(c_token,"p$oints")) {
				func_style = POINTS;
			}
			else 
				int_error("expecting 'lines', 'points', or 'impulses'",c_token);
			c_token++;
		}
		else
			int_error("unknown set option (try 'help set')",c_token);
	}
	else if (almost_equals(c_token,"sh$ow")) {
		if (almost_equals(++c_token,"f$unctions")) {
			c_token++;
			if (almost_equals(c_token,"s$tyle"))  {
				fprintf(stderr,"\nfunctions are plotted with ");
				switch (func_style) {
					case LINES: fprintf(stderr,"lines.\n\n"); break;
					case POINTS: fprintf(stderr,"points.\n\n"); break;
					case IMPULSES: fprintf(stderr,"impulses.\n\n"); break;
				}
			screen_ok = FALSE;
			c_token++;
			}
			else 
				view_functions();
		}
		else if (almost_equals(c_token,"v$ariables")) {
			view_variables();
			c_token++;
		}
		else if (almost_equals(c_token,"ac$tion_table") ||
				 equals(c_token,"at") ) {
			c_token++;
			view_at();
			c_token++;
		} 
		else if (almost_equals(c_token,"d$ata")) {
			c_token++;
			if (!almost_equals(c_token,"s$tyle")) 
				int_error("expecting keyword 'style'",c_token);
			fprintf(stderr,"\ndata is plotted with ");
			switch (data_style) {
				case LINES: fprintf(stderr,"lines.\n\n"); break;
				case POINTS: fprintf(stderr,"points.\n\n"); break;
				case IMPULSES: fprintf(stderr,"impulses.\n\n"); break;
			}
			screen_ok = FALSE;
			c_token++;
		} 
		else if (almost_equals(c_token,"x$range")) {
			fprintf(stderr,"\nxrange is [%g : %g]\n\n",xmin,xmax);
			screen_ok = FALSE;
			c_token++;
		} 
		else if (almost_equals(c_token,"y$range")) {
			fprintf(stderr,"\nyrange is [%g : %g]\n\n",ymin,ymax);
			screen_ok = FALSE;
			c_token++;
		} 
		else if (almost_equals(c_token,"z$ero")) {
			fprintf(stderr,"\nzero is %g\n\n",zero);
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"sa$mples")) {
			fprintf(stderr,"\nsampling rate is %d\n\n",samples);
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"o$utput")) {
			fprintf(stderr,"\noutput is sent to %s\n\n",outstr);
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"t$erminal")) {
			fprintf(stderr,"\nterminal type is %s\n\n",term_tbl[term].name);
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"au$toscale")) {
			fprintf(stderr,"\nautoscaling is %s\n\n",(autoscale)? "ON" : "OFF");
			screen_ok = FALSE;
			c_token++;
		}
		else if (almost_equals(c_token,"ve$rsion")) {
			(void) putc('\n',stderr);
			show_version(); 
			c_token++; 
		} 
		else if (almost_equals(c_token,"l$ogscale")) {
			if (log_x && log_y) 
				fprintf(stderr,"\nlogscaling both x and y axes\n\n");
			else if (log_x)
				fprintf(stderr,"\nlogscaling x axis\n\n");
			else if (log_y)
				fprintf(stderr,"\nlogscaling y axis\n\n");
			else 
				fprintf(stderr,"\nno logscaling\n\n");
			c_token++;
		}
		else if (almost_equals(c_token,"a$ll")) {
			c_token++;
			(void) putc('\n',stderr);
			show_version();
			fprintf(stderr,"data is plotted with ");
			switch (data_style) {
				case LINES: fprintf(stderr,"lines.\n"); break;
				case POINTS: fprintf(stderr,"points.\n"); break;
				case IMPULSES: fprintf(stderr,"impulses.\n"); break;
			}
			fprintf(stderr,"functions are plotted with ");
			switch (func_style) {
				case LINES: fprintf(stderr,"lines.\n"); break;
				case POINTS: fprintf(stderr,"points.\n"); break;
				case IMPULSES: fprintf(stderr,"impulses.\n"); break;
			}
			fprintf(stderr,"output is sent to %s\n",outstr);
			fprintf(stderr,"terminal type is %s\n",term_tbl[term].name);
			fprintf(stderr,"sampling rate is %d\n\n",samples);
			if (log_x && log_y) 
				fprintf(stderr,"logscaling both x and y axes\n");
			else if (log_x)
				fprintf(stderr,"logscaling x axis\n");
			else if (log_y)
				fprintf(stderr,"logscaling y axis\n");
			else 
				fprintf(stderr,"no logscaling\n");
			fprintf(stderr,"autoscaling is %s\n",(autoscale)? "ON" : "OFF");
			fprintf(stderr,"zero is %g\n",zero);
			fprintf(stderr,"xrange is [%g : %g]\n",xmin,xmax);
			fprintf(stderr,"yrange is [%g : %g]\n",ymin,ymax);
			view_variables();
			view_functions();
			c_token++;
		}
		else
			int_error("unknown show option (try 'help show')",c_token);
	}
	else if (almost_equals(c_token,"cl$ear")) { /* now does clear screen! */
		if (!term_init) {
			(*term_tbl[term].init)();
			term_init = TRUE;
		}
		(*term_tbl[term].graphics)();
		(*term_tbl[term].text)();
		(void) fflush(outfile);
		screen_ok = FALSE;
		c_token++;
	}
	else if (almost_equals(c_token,"she$ll")) {
		do_shell();
		screen_ok = FALSE;
		c_token++;
	}
	else if (almost_equals(c_token,"sa$ve")) {
		if (almost_equals(++c_token,"f$unctions")) {
			if (!isstring(++c_token))
				int_error("expecting filename",c_token);
			else {
				quote_str(sv_file,c_token);
				save_functions(fopen(sv_file,"w"));
			}
		}
		else if (almost_equals(c_token,"v$ariables")) {
			if (!isstring(++c_token))
				int_error("expecting filename",c_token);
			else {
				quote_str(sv_file,c_token);
				save_variables(fopen(sv_file,"w"));
			}
		}
		else if (isstring(c_token)) {
				quote_str(sv_file,c_token);
				save_all(fopen(sv_file,"w"));
		}
		else {
			int_error(
		"filename or keyword 'functions' or 'variables' expected",c_token);
		}
		c_token++;
	}
	else if (almost_equals(c_token,"l$oad")) {
		if (!isstring(++c_token))
			int_error("expecting filename",c_token);
		else {
			quote_str(sv_file,c_token);
			load_file(fopen(sv_file,"r"));	
		}
	/* input_line[] and token[] now destroyed! */
	}
	else if (almost_equals(c_token,"ex$it") ||
		almost_equals(c_token,"q$uit")) {
		done(IO_SUCCESS);
	}
	else if (!equals(c_token,";")) {		/* null statement */
		int_error("invalid command",c_token);
	}
}


load_range(a,b)
double *a,*b;
{
struct value t;

	if (equals(c_token,"]"))
		return;
	if (END_OF_COMMAND) {
	    int_error("starting range value or 'to' expected",c_token);
	} else if (!equals(c_token,"to") && !equals(c_token,":"))  {
		*a = real(const_express(&t));
	}	
	if (!equals(c_token,"to") && !equals(c_token,":")) 
		int_error("Keyword 'to' or ':' expected",c_token);
	c_token++; 
	if (!equals(c_token,"]"))
		*b = real(const_express(&t));
}


plotrequest()
{

	dummy_var[0] = 'x';  /* default */
	dummy_var[1] = '\0'; 
	if (equals(c_token,"[")) {
		c_token++;
		if (isletter(c_token)) {
			copy_str(dummy_var,c_token++);
			if (equals(c_token,"="))
				c_token++;
			else
				int_error("'=' expected",c_token);
		}
		load_range(&xmin,&xmax);
		if (!equals(c_token,"]"))
			int_error("']' expected",c_token);
		c_token++;
	}

	if (equals(c_token,"[")) { /* set optional y ranges */
		c_token++;
		load_range(&ymin,&ymax);
		autoscale = FALSE;
		if (!equals(c_token,"]"))
			int_error("']' expected",c_token);
		c_token++;
	}

	eval_plots();
}


define()
{
register int value,start_token;  /* start_token is the 1st token in the	*/
								/* function definition.			*/

	if (equals(c_token+1,"(")) {
		/* function ! */
		start_token = c_token;
		copy_str(dummy_var, c_token + 2);
		c_token += 5; /* skip (, dummy, ) and = */
		value = c_function = user_defined(start_token);
		build_at(&(udft[value].at));
				/* define User Defined Function (parse.c)*/
		capture(udft[value].definition,start_token,c_token-1);
	}
	else {
		/* variable ! */
		c_token +=2;
		(void) const_express(&vt[value = add_value(c_token - 2) ].vt_value);
		vt[value].vt_undef = FALSE;
	}
}


#define iscomment(c) (c == '!' || c == '#')

get_data(plot_num)
int plot_num;
{
static char data_file[MAX_ID_LEN+1], line[MAX_LINE_LEN+1];
register int i, l_num;
register FILE *fp;
float x, y;

	quote_str(data_file, c_token);
	plot[plot_num].plot_type = DATA;
	if (!(fp = fopen(data_file, "r")))
		os_error("can't open data file", c_token);

	l_num = 0;

	i = 0;
	while (fgets(line, MAX_LINE_LEN, fp)) {
		l_num++;
		if (iscomment(line[0]) || ! line[1])	/* line[0] will be '\n' */
			continue;		/* ignore comments  and blank lines */
		switch (sscanf(line, "%f %f", &x, &y)) {
			case 1:			/* only one number on the line */
				y = x;		/* assign that number to y */
				x = i;		/* and make the index into x */
			/* no break; !!! */
			case 2:
				if (x >= xmin && x <= xmax && (autoscale ||
					(y >= ymin && y <= ymax))) {
					if (log_x) {
						if (x <= 0.0)
							break;
						plot[plot_num].points[i].x = log10(x);
					} else
						plot[plot_num].points[i].x = x;
					if (log_y) {
						if (y <= 0.0)
							break;
						plot[plot_num].points[i].y = log10(y);
					} else
						plot[plot_num].points[i].y = y;
					if (autoscale) {
						if (y < ymin) ymin = y;
						if (y > ymax) ymax = y;
					}
					i++;
				}
				break;
			default:
				(void) sprintf(line, "bad data on line %d", l_num);
				int_error(line,c_token);
		}
	}
	plot[plot_num].count = i;
}


eval_plots()
{
register int i, plot_num, start_token, mysamples;
register double x_min, x_max, y_min, y_max, x;
register double xdiff, temp;
struct value a;

	/* don't sample higher than output device can handle! */
	mysamples = (samples <= term_tbl[term].xmax) ?samples :term_tbl[term].xmax;

	if (log_x) {
		if (xmin < 0.0 || xmax < 0.0)
			int_error("x range must be greater than 0 for log scale!",NO_CARET);
		x_min = log10(xmin);
		x_max = log10(xmax);
	} else {
		x_min = xmin;
		x_max = xmax;
	}

	if (autoscale) {
		ymin = HUGE;
		ymax = -HUGE;
	} else if (log_y && (ymin <= 0.0 || ymax <= 0.0))
			int_error("y range must be greater than 0 for log scale!",
				NO_CARET);

	xdiff = (x_max - x_min) / mysamples;

	c_function = MAX_UDFS;		/* last udft[] entry used for plots */

	plot_num = 0;

	while (TRUE) {
		if (END_OF_COMMAND)
			int_error("function to plot expected",c_token);
		if (plot_num == MAX_PLOTS || plot[plot_num].points == NULL)
			int_error("maximum number of plots exceeded",NO_CARET);

		start_token = c_token;

		if (is_definition(c_token)) {
			define();
		} else {
			if (isstring(c_token)) {			/* data file to plot */
				plot[plot_num].plot_type = DATA;
				plot[plot_num].plot_style = data_style;
				get_data(plot_num);
				c_token++;
			} 
			else {							/* function to plot */
				plot[plot_num].plot_type = FUNC;
				plot[plot_num].plot_style = func_style;
				build_at(&udft[MAX_UDFS].at);

				for (i = 0; i <= mysamples; i++) {
					if (i == samples+1)
						int_error("number of points exceeded samples",
							NO_CARET);
					x = x_min + i*xdiff;
					if (log_x)
						x = pow(10.0,x);
					(void) complex(&udft[MAX_UDFS].dummy_value, x, 0.0);
					
					evaluate_at(&udft[MAX_UDFS].at,&a);

					if (plot[plot_num].points[i].undefined =
						undefined || (fabs(imag(&a)) > zero))
							continue;

					temp = real(&a);

					if (log_y && temp <= 0.0) {
							plot[plot_num].points[i].undefined = TRUE;
							continue;
					}
					if (autoscale) {
						if (temp < ymin) ymin = temp;
						if (temp > ymax) ymax = temp;
					} else if (temp < ymin || temp > ymax) {
						plot[plot_num].points[i].undefined = TRUE;
						continue;
					}

					plot[plot_num].points[i].y = log_y ? log10(temp) : temp;
				}
				plot[plot_num].count = i; /* mysamples + 1 */
			}
			capture(plot[plot_num].title,start_token,c_token-1);
			if (almost_equals(c_token,"w$ith")) {
				c_token++;
				if (almost_equals(c_token,"l$ines")) {
					plot[plot_num].plot_style = LINES;
				} 
				else if (almost_equals(c_token,"i$mpulses")) {
					plot[plot_num].plot_style = IMPULSES;
				} 
				else if (almost_equals(c_token,"p$oints")) {
					plot[plot_num].plot_style = POINTS;
				} 
				else
					int_error("expecting 'lines', 'points', or 'impulses'",
					c_token);
				c_token++;
			}
			plot_num++;
		}

		if (equals(c_token,",")) 
			c_token++;
		else  
			break;
	}

	if (autoscale && (ymin == ymax))
		ymax += 1.0;	/* kludge to avoid divide-by-zero in do_plot */

	if (log_y) {
		y_min = log10(ymin);
		y_max = log10(ymax);
	} else {
		y_min = ymin;
		y_max = ymax;
	}
	do_plot(plot,plot_num,x_min,x_max,y_min,y_max);
}



done(status)
int status;
{
	if (term)
		(*term_tbl[term].reset)();
	exit(status);
}

#ifdef vms
do_shell()
{
	if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
		os_error("spawn error");
	}
}

#else /* vms */

#ifdef MSDOS

do_shell()
{
register char *comspec;
	if (!(comspec = getenv("COMSPEC")))
		comspec = "\command.com";
	if (spawnl(P_WAIT,comspec,NULL))
		os_error("unable to spawn shell");
}

#else /* MSDOS */

#ifdef VFORK

do_shell()
{
register char *shell;
register int p;
static int execstat;
	if (!(shell = getenv("SHELL")))
		shell = SHELL;
	if ((p = vfork()) == 0) {
		execstat = execl(shell,shell,NULL);
		_exit(1);
	} else if (p == -1)
		os_error("vfork failed",c_token);
	else
		while (wait(NULL) != p)
			;
	if (execstat == -1)
		os_error("shell exec failed",c_token);
	(void) putc('\n',stderr);
}
#else /* VFORK */

#define EXEC "exec "
do_shell()
{
static char exec[100] = EXEC;
register char *shell;
	if (!(shell = getenv("SHELL")))
		shell = SHELL;

	if (system(strcpy(&exec[sizeof(EXEC)-1],shell)))
		os_error("system() failed",NO_CARET);

	(void) putc('\n',stderr);
}
#endif /* VFORK */
#endif /* MSDOS */
#endif /* vms */
SHAR_EOF
if test 21464 -ne "`wc -c < 'command.c'`"
then
	echo shar: error transmitting "'command.c'" '(should have been 21464 characters)'
fi
chmod +x 'command.c'
fi # end of overwriting check
echo shar: extracting "'eval.c'" '(2739 characters)'
if test -f 'eval.c'
then
	echo shar: will not over-write existing file "'eval.c'"
else
cat << \SHAR_EOF > 'eval.c'
/*
 *
 *    G N U P L O T  --  eval.c
 *
 *  Copyright (C) 1986 Colin Kelley, Thomas Williams
 *
 *  You may use this code as you wish if credit is given and this message
 *  is retained.
 *
 *  Please e-mail any useful additions to vu-vlsi!plot so they may be
 *  included in later releases.
 *
 *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
 */

#include <stdio.h>
#include "plot.h"

extern int c_token,next_value,next_function;
extern struct udft_entry udft[];
extern struct ft_entry ft[];
extern struct vt_entry vt[];
extern struct at_type *curr_at;
extern struct lexical_unit token[];

struct value *integer();



int add_value(t_num)
int t_num;
{
register int i;

	/* check if it's already in the table... */

	for (i = 0; i < next_value; i++) {
		if (equals(t_num,vt[i].vt_name))
			return(i);
	}
	if (next_value == MAX_VALUES)
		int_error("user defined constant space full",NO_CARET);
	copy_str(vt[next_value].vt_name,t_num);
	vt[next_value].vt_value.type = INT;		/* not necessary, but safe! */
	vt[next_value].vt_undef = TRUE;
	return(next_value++);
}


add_action(sf_index,arg)
enum operators sf_index;
struct value *arg;

 /* argument to pass to standard function indexed by sf_index */
{

	if ( curr_at->count >= MAX_AT_LEN ) 
		int_error("action table overflow",NO_CARET);
	curr_at->actions[curr_at->count].index = ((int)sf_index);
	if (arg != (struct value *)0)
		curr_at->actions[curr_at->count].arg = *arg;
	curr_at->count++;
}


int standard(t_num)  /* return standard function index or 0 */
{
register int i;
	for (i = (int)SF_START; ft[i].ft_name != NULL; i++) {
		if (equals(t_num,ft[i].ft_name))
			return(i);
	}
	return(0);
}



int user_defined(t_num)  /* find or add function and return index */
int t_num; /* index to token[] */
{
register int i;
	for (i = 0; i < next_function; i++) {
		if (equals(t_num,udft[i].udft_name))
			return(i);
	}
	if (next_function == MAX_UDFS)
		int_error("user defined function space full",t_num);
	copy_str(udft[next_function].udft_name,t_num);
	udft[next_function].definition[0] = '\0';
	udft[next_function].at.count = 0;
	(void) integer(&udft[next_function].dummy_value, 0);
	return(next_function++);
}

 

execute_at(at_ptr)
struct at_type *at_ptr;
{
register int i;
	for (i = 0; i < at_ptr->count; i++) {
		(*ft[at_ptr->actions[i].index].funct)(&(at_ptr->actions[i].arg));
	}
}

/*

 'ft' is a table containing C functions within this program. 

 An 'action_table' contains pointers to these functions and arguments to be
 passed to them. 

 at_ptr is a pointer to the action table which must be executed (evaluated)

 so the iterated line exectues the function indexed by the at_ptr and 
 passes the argument which is pointed to by the arg_ptr 

*/
SHAR_EOF
if test 2739 -ne "`wc -c < 'eval.c'`"
then
	echo shar: error transmitting "'eval.c'" '(should have been 2739 characters)'
fi
chmod +x 'eval.c'
fi # end of overwriting check
echo shar: extracting "'graphics.c'" '(7182 characters)'
if test -f 'graphics.c'
then
	echo shar: will not over-write existing file "'graphics.c'"
else
cat << \SHAR_EOF > 'graphics.c'
/*
 *
 *    G N U P L O T  --  graphics.c
 *
 *  Copyright (C) 1986 Thomas Williams, Colin Kelley
 *
 *  You may use this code as you wish if credit is given and this message
 *  is retained.
 *
 *  Please e-mail any useful additions to vu-vlsi!plot so they may be
 *  included in later releases.
 *
 *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
 */

#include <stdio.h>
#include <math.h>
#include "plot.h"

char *strcpy(),*strncpy(),*strcat();

extern BOOLEAN autoscale;
extern FILE *outfile;
extern BOOLEAN log_x, log_y;
extern int term;

extern BOOLEAN screen_ok;
extern BOOLEAN term_init;

extern struct termentry term_tbl[];


#ifndef max		/* Lattice C has max() in math.h, but shouldn't! */
#define max(a,b) ((a > b) ? a : b)
#endif

#define map_x(x) (int)((x-xmin)*xscale) /* maps floating point x to screen */ 
#define map_y(y) (int)((y-ymin)*yscale)	/* same for y */


double raise(x,y)
double x;
int y;
{
register int i;
double val;

	val = 1.0;
	for (i=0; i < abs(y); i++)
		val *= x;
	if (y < 0 ) return (1.0/val);
	return(val);
}


double make_tics(tmin,tmax,logscale)
double tmin,tmax;
BOOLEAN logscale;
{
double xr,xnorm,tics,tic,l10;

	xr = fabs(tmin-tmax);
	
	l10 = log10(xr);
	if (logscale) {
		tic = raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
		if (tic < 1.0)
			tic = 1.0;
	} else {
		xnorm = pow(10.0,l10-(double)((l10 >= 0.0 ) ? (int)l10 : ((int)l10-1)));
		if (xnorm <= 2)
			tics = 0.2;
		else if (xnorm <= 5)
			tics = 0.5;
		else tics = 1.0;	
		tic = tics * raise(10.0,(l10 >= 0.0 ) ? (int)l10 : ((int)l10-1));
	}
	return(tic);
}

char *idx(a,b)
register char *a,b;
{
	do {
		if (*a == b)
			return(a);
	} while (*a++);
	return(0);
}

 
num2str(num,str)
double num;
char str[];
{
char temp[80];
char *a,*b;

 	if (fabs(num) > 9999.0 || fabs(num) < 0.001 && fabs(num) != 0.0) 
		(void) sprintf(temp,"%-.3e",num);	
	else
		(void) sprintf(temp,"%-.3g",num);
	if (b = idx(temp,'e')) {
		a = b-1;     /* b points to 'e'.  a points before 'e' */
		while ( *a == '0') /* trailing zeros */
			a--;	
		if ( *a == '.') 
			a--;
		(void) strncpy(str,temp,(int)(a-temp)+1);
		str[(int)(a-temp)+1] = '\0';
		a = b+1;	/* point to 1 after 'e' */
		if ( *a == '-') 
			(void) strcat(str,"e-");
		else	
			(void) strcat(str,"e");
		a++; /* advance a past '+' or '-' */
		while ( *a == '0' && *(a+1) != '\0') /* leading blanks */
			a++;
		(void) strcat(str,a); /* copy rest of string */
	}
	else
		(void) strcpy(str,temp);	
}


do_plot(plots, p_count, xmin, xmax, ymin, ymax)
struct curve_points plots[MAX_PLOTS];
int p_count;			/* count of plots to do */
double xmin, xmax;
double ymin, ymax;
{
register int curve, i, x, xaxis_y, yaxis_x,dp_count;
register BOOLEAN prev_undef;
register enum PLOT_TYPES p_type;
register double xscale, yscale;
register double ytic, xtic, least, most, ticplace;
register struct termentry *t = &term_tbl[term];
register int mms,mts;
static char xns[20],xms[20],yns[20],yms[20],xts[20],yts[20];
static char label[80];

	if (ymin == HUGE || ymax == -HUGE)
		int_error("all points undefined!", NO_CARET);

	ytic = make_tics(ymin,ymax,log_y);
	xtic = make_tics(xmin,xmax,log_x);
	dp_count = 0;
	
	if (ymin < ymax ) {
		ymin = ytic * floor(ymin/ytic);	
		ymax = ytic * ceil(ymax/ytic);
	}
	else {
		ymin = ytic * ceil(ymin/ytic);
		ymax = ytic * floor(ymax/ytic);
	}

	if (xmin == xmax)
		int_error("xmin should not equal xmax!",NO_CARET);
	if (ymin == ymax)
		int_error("ymin should not equal ymax!",NO_CARET);
	
	yscale = (t->ymax - 2)/(ymax - ymin);
	xscale = (t->xmax - 2)/(xmax - xmin);
	
	if (!term_init) {
		(*t->init)();
		term_init = TRUE;
	}
	screen_ok = FALSE;
	(*t->graphics)();
	(*t->linetype)(-2); /* border linetype */

	/* draw plot border */
	(*t->move)(0,0);	
	(*t->vector)(t->xmax-1,0);	
	(*t->vector)(t->xmax-1,t->ymax-1);	
	(*t->vector)(0,t->ymax-1);	
	(*t->vector)(0,0);

	least = (ymin < ymax) ? ymin : ymax;
	most = (ymin < ymax) ? ymax : ymin;

	for (ticplace = ytic + least; ticplace < most ; ticplace += ytic) { 
		(*t->move)(0,map_y(ticplace));
		(*t->vector)(t->h_tic,map_y(ticplace));
		(*t->move)(t->xmax-1,map_y(ticplace));
       	        (*t->vector)(t->xmax-1-t->h_tic,map_y(ticplace));
	}

	if (xmin < xmax ) {
		least = xtic * floor(xmin/xtic);	
		most = xtic * ceil(xmax/xtic);
	}
	else {
		least = xtic * ceil(xmin/xtic);
		most = xtic * floor(xmax/xtic);
	}

	for (ticplace = xtic + least; ticplace < most ; ticplace += xtic) { 
		(*t->move)(map_x(ticplace),0);
		(*t->vector)(map_x(ticplace),t->v_tic);
		(*t->move)(map_x(ticplace),t->ymax-1);
       	        (*t->vector)(map_x(ticplace),t->ymax-1-t->v_tic);
	}

	if (log_x) {
		num2str(pow(10.0,xmin),xns);
		num2str(pow(10.0,xmax),xms);
		num2str(pow(10.0,xtic),xts);
	}
	else {
		num2str(xmin,xns);
		num2str(xmax,xms);
		num2str(xtic,xts);
	}
	if (log_y) {
		num2str(pow(10.0,ymin),yns);
		num2str(pow(10.0,ymax),yms);
		num2str(pow(10.0,ytic),yts);
	} else {
		num2str(ymin,yns);
		num2str(ymax,yms);
		num2str(ytic,yts);
	}
	mms = max(strlen(xms),strlen(yms));
	mts = max(strlen(xts),strlen(yts));

	(void) sprintf(label,"%s < y < %-*s  inc = %-*s",yns,mms,yms,mts,yts);
	(*t->lrput_text)(0, label);
	(void) sprintf(label,"%s < x < %-*s  inc = %-*s",xns,mms,xms,mts,xts);
	(*t->lrput_text)(1, label);


/* DRAW AXES */
	(*t->linetype)(-1);	/* axis line type */
	xaxis_y = map_y(0.0);
	yaxis_x = map_x(0.0); 

	if (xaxis_y < 0)
		xaxis_y = 0;				/* save for impulse plotting */
	else if (xaxis_y >= t->ymax)
		xaxis_y = t->ymax - 1;
	else if (!log_y) {
		(*t->move)(0,xaxis_y);
		(*t->vector)((t->xmax-1),xaxis_y);
	}

	if (!log_x && yaxis_x >= 0 && yaxis_x < t->xmax) {
		(*t->move)(yaxis_x,0);
		(*t->vector)(yaxis_x,(t->ymax-1));
	}

/* DRAW CURVES */
	for (curve = 0; curve < p_count; curve++) {
		(*t->linetype)(curve);
		(*t->ulput_text)(curve, plots[curve].title);
		(*t->linetype)(curve);

		p_type = plots[curve].plot_type;
		switch(plots[curve].plot_style) {
			case IMPULSES:
				for (i = 0; i < plots[curve].count; i++) {
					if (!plots[curve].points[i].undefined) {
						if (p_type == DATA)
							x = map_x(plots[curve].points[i].x);
						else
							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
						(*t->move)(x,xaxis_y);
						(*t->vector)(x,map_y(plots[curve].points[i].y));
					}
				}
				break;
			case LINES:
				prev_undef = TRUE;
				for (i = 0; i < plots[curve].count; i++) {
					if (!plots[curve].points[i].undefined) {
						if (p_type == DATA)
							x = map_x(plots[curve].points[i].x);
						else
							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
						if (prev_undef)
							(*t->move)(x,
							map_y(plots[curve].points[i].y));
						(*t->vector)(x,
							map_y(plots[curve].points[i].y));
					}
					prev_undef = plots[curve].points[i].undefined;
				}
				break;
			case POINTS:
				for (i = 0; i < plots[curve].count; i++) {
					if (!plots[curve].points[i].undefined) {
						if (p_type == DATA)
							x = map_x(plots[curve].points[i].x);
						else
							x = (long)(t->xmax-1)*i/(plots[curve].count-1);
						(*t->point)(x,map_y(plots[curve].points[i].y),dp_count);
					}
				}
				dp_count++;
				break;

		}
	}
	(*t->text)();
	(void) fflush(outfile);
}
SHAR_EOF
if test 7182 -ne "`wc -c < 'graphics.c'`"
then
	echo shar: error transmitting "'graphics.c'" '(should have been 7182 characters)'
fi
chmod +x 'graphics.c'
fi # end of overwriting check
echo shar: extracting "'internal.c'" '(12514 characters)'
if test -f 'internal.c'
then
	echo shar: will not over-write existing file "'internal.c'"
else
cat << \SHAR_EOF > 'internal.c'
/*
 *
 *    G N U P L O T  --  internal.c
 *
 *  Copyright (C) 1986 Colin Kelley, Thomas Williams
 *
 *  You may use this code as you wish if credit is given and this message
 *  is retained.
 *
 *  Please e-mail any useful additions to vu-vlsi!plot so they may be
 *  included in later releases.
 *
 *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
 */

#include <math.h>
#include <stdio.h>
#include "plot.h"

extern BOOLEAN undefined;
extern struct vt_entry vt[MAX_VALUES];
extern struct udft_entry udft[MAX_UDFS];

char *strcpy();

struct value *pop(), *complex(), *integer();
double magnitude(), angle(), real();

struct value stack[STACK_DEPTH];

int s_p = -1;   /* stack pointer */


/*
 * System V and MSC 4.0 call this when they wants to print an error message.
 * Don't!
 */
matherr()
{
	return (undefined = TRUE);		/* don't print error message */
}


reset_stack()
{
	s_p = -1;
}


check_stack()	/* make sure stack's empty */
{
	if (s_p != -1)
		fprintf(stderr,"\nwarning:  internal error--stack not empty!\n");
}


struct value *pop(x)
struct value *x;
{
	if (s_p  < 0 )
		int_error("stack underflow",NO_CARET);
	*x = stack[s_p--];
	return(x);
}

#define ERR_VAR "undefined variable: "

f_push(x)
struct value *x;		/* contains index of value to push; must be integer! */
{
static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
register int index;

	if (x->type != INT)
		int_error("internal error--non-int passed to f_push!",NO_CARET);
	index = x->v.int_val;

	if (vt[index].vt_undef) {	 /* undefined */
		(void) strcpy(&err_str[sizeof(ERR_VAR) - 1], vt[index].vt_name);
		int_error(err_str,NO_CARET);
	}
	push(&vt[index].vt_value);
}


f_pushc(x)
struct value *x;
{
	if (s_p == STACK_DEPTH - 1)
		int_error("stack overflow",NO_CARET);
	stack[++s_p] = *x;
}


f_pushd(x)
struct value *x;
{
	f_pushc(&udft[x->v.int_val].dummy_value);
}


#define ERR_FUN "undefined function: "

f_call(f_index)  /* execute a udf */
struct value *f_index;
{
static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;

	if (udft[f_index->v.int_val].at.count == 0) { /* undefined */
		(void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
				udft[f_index->v.int_val].udft_name);
		int_error(err_str,NO_CARET);
	}
	(void) pop(&udft[f_index->v.int_val].dummy_value);

	execute_at(&udft[f_index->v.int_val].at);
}


static int_check(v)
struct value *v;
{
	if (v->type != INT)
		int_error("non-integer passed to boolean operator",NO_CARET);
}


f_terniary()		/* code for (a) ? b : c */
{
struct value a, b, c;
	(void) pop(&c);	(void) pop(&b);	int_check(pop(&a));
	push((a.v.int_val) ? &b : &c);
			/* I just had to use ? : here! */
}


f_lnot()
{
struct value a;
	int_check(pop(&a));
	push(integer(&a,!a.v.int_val) );
}


f_bnot()
{
struct value a;
	int_check(pop(&a));
	push( integer(&a,~a.v.int_val) );
}


f_lor()
{
struct value a,b;
	int_check(pop(&b));
	int_check(pop(&a));
	push( integer(&a,a.v.int_val || b.v.int_val) );
}


f_land()
{
struct value a,b;
	int_check(pop(&b));
	int_check(pop(&a));
	push( integer(&a,a.v.int_val && b.v.int_val) );
}


f_bor()
{
struct value a,b;
	int_check(pop(&b));
	int_check(pop(&a));
	push( integer(&a,a.v.int_val | b.v.int_val) );
}


f_xor()
{
struct value a,b;
	int_check(pop(&b));
	int_check(pop(&a));
	push( integer(&a,a.v.int_val ^ b.v.int_val) );
}


f_band()
{
struct value a,b;
	int_check(pop(&b));
	int_check(pop(&a));
	push( integer(&a,a.v.int_val & b.v.int_val) );
}


f_uminus()
{
struct value a;
	(void) pop(&a);
	switch(a.type) {
		case INT:
			a.v.int_val = -a.v.int_val;
			break;
		case CMPLX:
			a.v.cmplx_val.real =
				-a.v.cmplx_val.real;
			a.v.cmplx_val.imag =
				-a.v.cmplx_val.imag;
	}
	push(&a);
}


f_eq() /* note: floating point equality is rare because of roundoff error! */
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val ==
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val ==
						b.v.cmplx_val.real &&
					   b.v.cmplx_val.imag == 0.0);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (b.v.int_val == a.v.cmplx_val.real &&
					   a.v.cmplx_val.imag == 0.0);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real==
						b.v.cmplx_val.real &&
						a.v.cmplx_val.imag==
						b.v.cmplx_val.imag);
			}
	}
	push(integer(&a,result));
}


f_ne()
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val !=
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val !=
						b.v.cmplx_val.real ||
					   b.v.cmplx_val.imag != 0.0);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (b.v.int_val !=
						a.v.cmplx_val.real ||
					   a.v.cmplx_val.imag != 0.0);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real !=
						b.v.cmplx_val.real ||
						a.v.cmplx_val.imag !=
						b.v.cmplx_val.imag);
			}
	}
	push(integer(&a,result));
}


f_gt()
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val >
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val >
						b.v.cmplx_val.real);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (a.v.cmplx_val.real >
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real >
						b.v.cmplx_val.real);
			}
	}
	push(integer(&a,result));
}


f_lt()
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val <
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val <
						b.v.cmplx_val.real);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (a.v.cmplx_val.real <
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real <
						b.v.cmplx_val.real);
			}
	}
	push(integer(&a,result));
}


f_ge()
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val >=
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val >=
						b.v.cmplx_val.real);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (a.v.cmplx_val.real >=
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real >=
						b.v.cmplx_val.real);
			}
	}
	push(integer(&a,result));
}


f_le()
{
struct value a, b;
	register int result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					result = (a.v.int_val <=
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.int_val <=
						b.v.cmplx_val.real);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					result = (a.v.cmplx_val.real <=
						b.v.int_val);
					break;
				case CMPLX:
					result = (a.v.cmplx_val.real <=
						b.v.cmplx_val.real);
			}
	}
	push(integer(&a,result));
}


f_plus()
{
struct value a, b, result;
	(void) pop(&b);
	(void) pop(&a);
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					(void) integer(&result,a.v.int_val +
						b.v.int_val);
					break;
				case CMPLX:
					(void) complex(&result,a.v.int_val +
						b.v.cmplx_val.real,
					   b.v.cmplx_val.imag);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					(void) complex(&result,b.v.int_val +
						a.v.cmplx_val.real,
					   a.v.cmplx_val.imag);
					break;
				case CMPLX:
					(void) complex(&result,a.v.cmplx_val.real+
						b.v.cmplx_val.real,
						a.v.cmplx_val.imag+
						b.v.cmplx_val.imag);
			}
	}
	push(&result);
}


f_minus()
{
struct value a, b, result;
	(void) pop(&b);
	(void) pop(&a);		/* now do a - b */
	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					(void) integer(&result,a.v.int_val -
						b.v.int_val);
					break;
				case CMPLX:
					(void) complex(&result,a.v.int_val -
						b.v.cmplx_val.real,
					   -b.v.cmplx_val.imag);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					(void) complex(&result,a.v.cmplx_val.real -
						b.v.int_val,
					    a.v.cmplx_val.imag);
					break;
				case CMPLX:
					(void) complex(&result,a.v.cmplx_val.real-
						b.v.cmplx_val.real,
						a.v.cmplx_val.imag-
						b.v.cmplx_val.imag);
			}
	}
	push(&result);
}


f_mult()
{
struct value a, b, result;
	(void) pop(&b);
	(void) pop(&a);	/* now do a*b */

	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					(void) integer(&result,a.v.int_val *
						b.v.int_val);
					break;
				case CMPLX:
					(void) complex(&result,a.v.int_val *
						b.v.cmplx_val.real,
						a.v.int_val *
						b.v.cmplx_val.imag);
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					(void) complex(&result,b.v.int_val *
						a.v.cmplx_val.real,
						b.v.int_val *
						a.v.cmplx_val.imag);
					break;
				case CMPLX:
					(void) complex(&result,a.v.cmplx_val.real*
						b.v.cmplx_val.real-
						a.v.cmplx_val.imag*
						b.v.cmplx_val.imag,
						a.v.cmplx_val.real*
						b.v.cmplx_val.imag+
						a.v.cmplx_val.imag*
						b.v.cmplx_val.real);
			}
	}
	push(&result);
}


f_div()
{
struct value a, b, result;
register double square;
	(void) pop(&b);
	(void) pop(&a);	/* now do a/b */

	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					if (b.v.int_val)
					  (void) integer(&result,a.v.int_val /
						b.v.int_val);
					else {
					  (void) integer(&result,0);
					  undefined = TRUE;
					}
					break;
				case CMPLX:
					square = b.v.cmplx_val.real*
						b.v.cmplx_val.real +
						b.v.cmplx_val.imag*
						b.v.cmplx_val.imag;
					if (square)
						(void) complex(&result,a.v.int_val*
						b.v.cmplx_val.real/square,
						-a.v.int_val*
						b.v.cmplx_val.imag/square);
					else {
						(void) complex(&result,0.0,0.0);
						undefined = TRUE;
					}
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					if (b.v.int_val)
					  
					  (void) complex(&result,a.v.cmplx_val.real/
						b.v.int_val,
						a.v.cmplx_val.imag/
						b.v.int_val);
					else {
						(void) complex(&result,0.0,0.0);
						undefined = TRUE;
					}
					break;
				case CMPLX:
					square = b.v.cmplx_val.real*
						b.v.cmplx_val.real +
						b.v.cmplx_val.imag*
						b.v.cmplx_val.imag;
					if (square)
					(void) complex(&result,(a.v.cmplx_val.real*
						b.v.cmplx_val.real+
						a.v.cmplx_val.imag*
						b.v.cmplx_val.imag)/square,
						(a.v.cmplx_val.imag*
						b.v.cmplx_val.real-
						a.v.cmplx_val.real*
						b.v.cmplx_val.imag)/
							square);
					else {
						(void) complex(&result,0.0,0.0);
						undefined = TRUE;
					}
			}
	}
	push(&result);
}


f_mod()
{
struct value a, b;
	(void) pop(&b);
	(void) pop(&a);	/* now do a%b */

	if (a.type != INT || b.type != INT)
		int_error("can only mod ints",NO_CARET);
	if (b.v.int_val)
		push(integer(&a,a.v.int_val % b.v.int_val));
	else {
		push(integer(&a,0));
		undefined = TRUE;
	}
}


f_power()
{
struct value a, b, result;
register int i, t, count;
register double mag, ang;
	(void) pop(&b);
	(void) pop(&a);	/* now find a**b */

	switch(a.type) {
		case INT:
			switch (b.type) {
				case INT:
					count = abs(b.v.int_val);
					t = 1;
					for(i=0; i < count; i++)
						t *= a.v.int_val;
					if (b.v.int_val >= 0)
						(void) integer(&result,t);
					else
						(void) complex(&result,1.0/t,0.0);
					break;
				case CMPLX:
					mag =
					  pow(magnitude(&a),fabs(b.v.cmplx_val.real));
					if (b.v.cmplx_val.real < 0.0)
						mag = 1.0/mag;
					ang = angle(&a)*b.v.cmplx_val.real+
					  b.v.cmplx_val.imag;
					(void) complex(&result,mag*cos(ang),
						mag*sin(ang));
			}
			break;
		case CMPLX:
			switch (b.type) {
				case INT:
					/* not so good, but...! */
					mag =
					  pow(magnitude(&a),(double)abs(b.v.int_val));
					if (b.v.int_val < 0)
						mag = 1.0/mag;
					ang = angle(&a)*b.v.int_val;
					(void) complex(&result,mag*cos(ang),
						mag*sin(ang));
					break;
				case CMPLX:
					mag =
					  pow(magnitude(&a),fabs(b.v.cmplx_val.real));
					if (b.v.cmplx_val.real < 0.0)
					  mag = 1.0/mag;
					ang = angle(&a)*b.v.cmplx_val.real+
					  b.v.cmplx_val.imag;
					(void) complex(&result,mag*cos(ang),
						mag*sin(ang));
			}
	}
	push(&result);
}
SHAR_EOF
if test 12514 -ne "`wc -c < 'internal.c'`"
then
	echo shar: error transmitting "'internal.c'" '(should have been 12514 characters)'
fi
chmod +x 'internal.c'
fi # end of overwriting check
echo shar: extracting "'misc.c'" '(4466 characters)'
if test -f 'misc.c'
then
	echo shar: will not over-write existing file "'misc.c'"
else
cat << \SHAR_EOF > 'misc.c'
/*
 *
 *    G N U P L O T  --  misc.c
 *
 *  Copyright (C) 1986 Thomas Williams, Colin Kelley
 *
 *  You may use this code as you wish if credit is given and this message
 *  is retained.
 *
 *  Please e-mail any useful additions to vu-vlsi!plot so they may be
 *  included in later releases.
 *
 *  This file should be edited with 4-column tabs!  (:set ts=4 sw=4 in vi)
 */

#include <stdio.h>
#include "plot.h"

extern BOOLEAN screen_ok;

extern struct curve_points plot[];
extern int c_token,next_value,next_function;
extern struct udft_entry udft[];
extern struct at_type *curr_at;
extern struct ft_entry ft[];
extern struct vt_entry vt[];

char *malloc();


pointmem(samples)
int samples;
{
register int i;
	for (i = MAX_PLOTS-1; i >= 0; i--)
		if (plot[i].points != NULL) {
			free(plot[i].points);
			plot[i].points = NULL;
		}
	for (i = 0; i < MAX_PLOTS; i++)
		if ((plot[i].points = (struct coordinate *)
			malloc((samples+1) * sizeof(struct coordinate))) == NULL) {
				fprintf(stderr,"only space for %d plots\n",i);
				screen_ok = FALSE;
				break;
			}
}


save_functions(fp)
FILE *fp;
{
int i;
	
	if (fp == 0)
		os_error("Cannot open save file",c_token);			
	else {
		for (i=0; i < next_function; i++)
			fprintf(fp,"%s\n",udft[i].definition);
	}
	(void) fclose(fp);
}


save_variables(fp)
FILE *fp;
{
int i;

	if (fp == 0) 
		os_error("Cannot open save file",c_token);			
	else {
		for (i=0; i < next_value; i++) {
			fprintf(fp,"%s = ",vt[i].vt_name);
			show_value(fp,&vt[i].vt_value);
			(void) putc('\n',fp);
		}
	}
	(void) fclose(fp);
}


save_all(fp)
FILE *fp;
{
int i;

	if (fp == 0) 
		os_error("Cannot open save file",c_token);			
	else {
		for (i=0; i < next_function; i++)
			fprintf(fp,"%s\n",udft[i].definition);
		for (i=0; i < next_value; i++) {
			fprintf(fp,"%s = ",vt[i].vt_name);
			show_value(fp,&vt[i].vt_value);
			(void) putc('\n',fp);
		}
	}
	(void) fclose(fp);
}


load_file(fp)
FILE *fp;
{
register int len;
extern char input_line[];

	if ( fp == 0 ) 
		os_error("Cannot open load file",c_token);
	else {
		while (fgets(input_line,MAX_LINE_LEN,fp)) {
			len = strlen(input_line) - 1;
			if (input_line[len] == '\n')
				input_line[len] = '\0';

			screen_ok = FALSE;	/* make sure command line is
					   echoed on error */
			do_line();
		}
	}
	(void) fclose(fp);
}



view_variables()
{
int i;

	screen_ok = FALSE;
	fprintf(stderr,"\nVariables:\n");
	for (i=0; i < next_value; i++) {
		fprintf(stderr,"%-*s ",MAX_ID_LEN,vt[i].vt_name);
		if (vt[i].vt_undef)
			fputs("is undefined\n",stderr);
		else {
			fputs("= ",stderr);
			show_value(stderr,&vt[i].vt_value);
			(void) putc('\n',stderr);
		}
	}
	(void) putc('\n',stderr);
}


view_functions()
{
int i;
	screen_ok = FALSE;
	fprintf(stderr,"\nUser-Defined Functions:\n");
	for (i=0; i < next_function; i++) 
		if (udft[i].at.count == 0) 
			fprintf(stderr,"%s is undefined\n",udft[i].udft_name);
		else
			fprintf(stderr,"%s\n",udft[i].definition);
	(void) putc('\n',stderr);
}


view_at()
{
static struct at_type at;
	screen_ok = FALSE;
	build_at(&at);		/* build action table in at */
	(void) putc('\n',stderr);
	show_at(0);
	(void) putc('\n',stderr);
}


show_at(level)
int level;
{
struct at_type *at_address;
int i, j;
struct value *arg;

	at_address = curr_at;
	for (i = 0; i < at_address->count; i++) {
		for (j = 0; j < level; j++)
			(void) putc(' ',stderr);	/* indent */

			/* print name of action instruction */
		fputs(ft[at_address->actions[i].index].ft_name,stderr);
		arg = &(at_address->actions[i].arg);
			/* now print optional argument */

		switch(at_address->actions[i].index) {
		  case (int)PUSH:	fprintf(stderr," (%s)\n",
					  vt[arg->v.int_val].vt_name);
					break;
		  case (int)PUSHC:	(void) putc('(',stderr);
					show_value(stderr,arg);
					fputs(")\n",stderr);
					break;
		  case (int)PUSHD:	fprintf(stderr," (%s dummy)\n",
					  udft[arg->v.int_val].udft_name);
					break;
		  case (int)CALL:	fprintf(stderr," (%s)\n",
					  udft[arg->v.int_val].udft_name);
					curr_at = &udft[arg->v.int_val].at;
					show_at(level+2); /* recurse! */
					curr_at = at_address;
					break;
		  default:
					(void) putc('\n',stderr);
		}
	}
}

#ifdef vms
#define OS "vms"
#endif

#ifdef unix
#define OS "unix"
#endif

#ifdef MSDOS
#define OS "MS-DOS"
#endif

#ifndef OS
#define OS ""
#endif

show_version()
{
	extern char version[];
	extern char date[];
	screen_ok = FALSE;
	fprintf(stderr,"%s v%s (%s);  %s\n\n", PROGRAM, version, OS, date);
}
SHAR_EOF
if test 4466 -ne "`wc -c < 'misc.c'`"
then
	echo shar: error transmitting "'misc.c'" '(should have been 4466 characters)'
fi
chmod +x 'misc.c'
fi # end of overwriting check
#	End of shell archive
exit 0



More information about the Comp.sources.unix mailing list