GNUPLOT 1.1: part 2 of 6
williams at vu-vlsi.UUCP
williams at vu-vlsi.UUCP
Thu Jan 29 04:20:00 AEST 1987
GNUPLOT 1.1: part 2 of 6
--------------------------------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
# parse.c
# This archive created: Tue Jan 27 13:21:33 1987
export PATH; PATH=/bin:$PATH
echo shar: extracting "'command.c'" '(21346 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, 1987 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>
#ifdef MSDOS
#include <process.h>
#endif
#include "plot.h"
#ifndef STDOUT
#define STDOUT 1
#endif
/*
* global variables to hold status of 'set' options
*
*/
BOOLEAN autoscale = TRUE;
char dummy_var[MAX_ID_LEN+1] = "x";
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.0,
xmax = 10.0,
ymin = -10.0,
ymax = 10.0;
double zero = ZERO; /* zero threshold, not 0! */
BOOLEAN screen_ok;
BOOLEAN term_init;
BOOLEAN undefined;
/*
* instead of <strings.h>
*/
char *gets(),*getenv();
char *strcpy(),*strncpy(),*strcat();
char *malloc();
double magnitude(),angle(),real(),imag();
struct value *const_express(), *pop(), *complex();
struct at_type *temp_at(), *perm_at();
struct udft_entry *add_udf();
struct udvt_entry *add_udv();
extern struct termentry term_tbl[];
struct lexical_unit token[MAX_TOKENS];
char input_line[MAX_LINE_LEN+1] = "set term ";
char c_dummy_var[MAX_ID_LEN+1]; /* current dummy var */
int num_tokens, c_token;
struct curve_points *first_plot = NULL;
struct udft_entry plot_func, *dummy_func;
static char replot_line[MAX_LINE_LEN+1];
static int plot_token; /* start of 'plot' command */
static char help[MAX_LINE_LEN] = HELP;
com_line()
{
read_line();
screen_ok = TRUE; /* so we can flag any new output */
do_line();
}
do_line() /* also used in load_file */
{
if (is_comment(input_line[0]))
return;
if (is_system(input_line[0])) {
do_system();
fputs("!\n",stderr);
return;
}
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()
{
static char sv_file[MAX_LINE_LEN+1];
/* string holding name of save or load file */
c_dummy_var[0] = '\0'; /* no dummy variable */
if (is_definition(c_token))
define();
else if (equals(c_token,"help") || equals(c_token,"?")) {
register int len;
register char *help_ptr;
c_token++;
if ((help_ptr = getenv("GNUHELP"))) /* initial command */
(void) strncpy(help,help_ptr,sizeof(help) - 1);
else
(void) strncpy(help,HELP,sizeof(help) - 1);
while (!(END_OF_COMMAND)) {
len = strlen(help);
help[len] = ' '; /* put blank between help segments */
copy_str(help+len+1,c_token++);
}
do_help();
screen_ok = FALSE;
c_token++;
}
else if (almost_equals(c_token,"pr$int")) {
struct value a;
c_token++;
(void) const_express(&a);
(void) putc('\t',stderr);
disp_value(stderr,&a);
(void) putc('\n',stderr);
screen_ok = FALSE;
}
else if (almost_equals(c_token,"p$lot")) {
plot_token = c_token++;
plotrequest();
}
else if (almost_equals(c_token,"rep$lot")) {
if (replot_line[0] == '\0')
int_error("no previous plot",c_token);
(void) strcpy(input_line,replot_line);
screen_ok = FALSE;
num_tokens = scanner(input_line);
c_token = 1; /* skip the 'plot' part */
plotrequest();
}
else if (almost_equals(c_token,"se$t"))
set_stuff();
else if (almost_equals(c_token,"sh$ow"))
show_stuff();
else if (almost_equals(c_token,"cl$ear")) {
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! */
c_token = num_tokens = 0;
}
}
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);
}
}
enum PLOT_STYLE
get_style()
{
register enum PLOT_STYLE ps;
c_token++;
if (almost_equals(c_token,"l$ines"))
ps = LINES;
else if (almost_equals(c_token,"i$mpulses"))
ps = IMPULSES;
else if (almost_equals(c_token,"p$oints"))
ps = POINTS;
else
int_error("expecting 'lines', 'points', or 'impulses'",c_token);
c_token++;
return(ps);
}
set_stuff()
{
static char testfile[MAX_LINE_LEN+1];
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,"d$ata")) {
c_token++;
if (!almost_equals(c_token,"s$tyle"))
int_error("expecting keyword 'style'",c_token);
data_style = get_style();
}
else if (almost_equals(c_token,"d$ummy")) {
c_token++;
copy_str(dummy_var,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);
func_style = get_style();
}
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,"nol$ogscale")) {
log_x = log_y = FALSE;
c_token++;
}
else if (almost_equals(c_token,"o$utput")) {
register FILE *f;
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(testfile,c_token);
if (!(f = fopen(testfile,"w"))) {
os_error("cannot open file; output not changed",c_token);
}
(void) fclose(outfile);
outfile = f;
term_init = FALSE;
outstr[0] = '\'';
(void) strcat(strcpy(outstr+1,testfile),"'");
}
c_token++;
}
else if (almost_equals(c_token,"sa$mples")) {
register int tsamp;
struct value a;
c_token++;
tsamp = (int)magnitude(const_express(&a));
if (tsamp < 1)
int_error("sampling rate must be > 0; sampling unchanged",
c_token);
else {
register struct curve_points *f_p = first_plot;
first_plot = NULL;
cp_free(f_p);
samples = tsamp;
}
}
else if (almost_equals(c_token,"t$erminal")) {
c_token++;
if (END_OF_COMMAND) {
list_terms();
screen_ok = FALSE;
}
else
term = set_term(c_token);
c_token++;
}
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,"z$ero")) {
struct value a;
c_token++;
zero = magnitude(const_express(&a));
}
else
int_error(
"valid set options: '[no]autoscale', 'data', 'dummy', 'function',\n\
'[no]logscale', 'output', 'samples', 'terminal', 'xrange', 'yrange', 'zero'",
c_token);
}
show_stuff()
{
if (almost_equals(++c_token,"ac$tion_table") ||
equals(c_token,"at") ) {
c_token++;
show_at();
c_token++;
}
else if (almost_equals(c_token,"au$toscale")) {
(void) putc('\n',stderr);
show_autoscale();
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);
(void) putc('\n',stderr);
show_style("data",data_style);
c_token++;
}
else if (almost_equals(c_token,"d$ummy")) {
fprintf(stderr,"\n\tdummy variable is %s\n",dummy_var);
c_token++;
}
else if (almost_equals(c_token,"f$unctions")) {
c_token++;
if (almost_equals(c_token,"s$tyle")) {
(void) putc('\n',stderr);
show_style("functions",func_style);
c_token++;
}
else
show_functions();
}
else if (almost_equals(c_token,"l$ogscale")) {
(void) putc('\n',stderr);
show_logscale();
c_token++;
}
else if (almost_equals(c_token,"o$utput")) {
(void) putc('\n',stderr);
show_output();
c_token++;
}
else if (almost_equals(c_token,"sa$mples")) {
(void) putc('\n',stderr);
show_samples();
c_token++;
}
else if (almost_equals(c_token,"t$erminal")) {
(void) putc('\n',stderr);
show_term();
c_token++;
}
else if (almost_equals(c_token,"v$ariables")) {
show_variables();
c_token++;
}
else if (almost_equals(c_token,"ve$rsion")) {
show_version();
c_token++;
}
else if (almost_equals(c_token,"x$range")) {
(void) putc('\n',stderr);
show_range('x',xmin,xmax);
c_token++;
}
else if (almost_equals(c_token,"y$range")) {
(void) putc('\n',stderr);
show_range('y',ymin,ymax);
c_token++;
}
else if (almost_equals(c_token,"z$ero")) {
(void) putc('\n',stderr);
show_zero();
c_token++;
}
else if (almost_equals(c_token,"a$ll")) {
c_token++;
show_version();
fprintf(stderr,"\tdummy variable is %s\n",dummy_var);
show_style("data",data_style);
show_style("functions",func_style);
show_output();
show_term();
show_samples();
show_logscale();
show_autoscale();
show_zero();
show_range('x',xmin,xmax);
show_range('y',ymin,ymax);
show_variables();
show_functions();
c_token++;
}
else
int_error(
"valid show options: 'action_table', 'all', 'autoscale', 'data',\n\
'dummy', 'function', 'logscale', 'output', 'samples', 'terminal',\n\
'variables', 'version', 'xrange', 'yrange', 'zero'", c_token);
screen_ok = FALSE;
(void) putc('\n',stderr);
}
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 ':' 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("':' expected",c_token);
c_token++;
if (!equals(c_token,"]"))
*b = real(const_express(&t));
}
plotrequest()
{
if (!term) /* unknown */
int_error("use 'set term' to set terminal type first",c_token);
if (equals(c_token,"[")) {
c_token++;
if (isletter(c_token)) {
copy_str(c_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 start_token; /* the 1st token in the function definition */
register struct udvt_entry *udv;
register struct udft_entry *udf;
if (equals(c_token+1,"(")) {
/* function ! */
start_token = c_token;
copy_str(c_dummy_var, c_token + 2);
c_token += 5; /* skip (, dummy, ) and = */
if (END_OF_COMMAND)
int_error("function definition expected",c_token);
udf = dummy_func = add_udf(start_token);
if (udf->at) /* already a dynamic a.t. there */
free((char *)udf->at); /* so free it first */
if (!(udf->at = perm_at()))
int_error("not enough memory for function",start_token);
m_capture(&(udf->definition),start_token,c_token-1);
}
else {
/* variable ! */
start_token = c_token;
c_token +=2;
udv = add_udv(start_token);
(void) const_express(&(udv->udv_value));
udv->udv_undef = FALSE;
}
}
get_data(this_plot)
struct curve_points *this_plot;
{
static char data_file[MAX_LINE_LEN+1], line[MAX_LINE_LEN+1];
register int i, overflow, l_num;
register FILE *fp;
float x, y;
quote_str(data_file, c_token);
this_plot->plot_type = DATA;
if (!(fp = fopen(data_file, "r")))
os_error("can't open data file", c_token);
l_num = 0;
overflow = i = 0;
while (fgets(line, MAX_LINE_LEN, fp)) {
l_num++;
if (is_comment(line[0]) || ! line[1]) /* line[0] will be '\n' */
continue; /* ignore comments and blank lines */
if (i == samples+1) {
overflow = i; /* keep track for error message later */
i--; /* so we don't fall off end of points[i] */
}
switch (sscanf(line, "%f %f", &x, &y)) {
case 1: /* only one number on the line */
y = x; /* so use it as the y value, */
x = i; /* and use the index as the x */
/* no break; !!! */
case 2:
this_plot->points[i].undefined = TRUE;
if (x >= xmin && x <= xmax && (autoscale ||
(y >= ymin && y <= ymax))) {
if (log_x) {
if (x <= 0.0)
break;
this_plot->points[i].x = log10(x);
} else
this_plot->points[i].x = x;
if (log_y) {
if (y <= 0.0)
break;
this_plot->points[i].y = log10(y);
} else
this_plot->points[i].y = y;
if (autoscale) {
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
this_plot->points[i].undefined = FALSE;
}
if (overflow)
overflow++;
else
i++;
break;
default:
(void) sprintf(line, "bad data on line %d", l_num);
int_error(line,c_token);
}
}
if (overflow) {
(void) sprintf(line,
"%d data points found--samples must be set at least this high",overflow);
/* actually, samples can be one less! */
int_error(line,c_token);
}
this_plot->p_count = i;
(void) fclose(fp);
}
eval_plots()
{
register int i;
register struct curve_points *this_plot, **tp_ptr;
register int start_token, mysamples;
register double x_min, x_max, y_min, y_max, x;
register double xdiff, temp;
register int plot_num;
static 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 above 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 above 0 for log scale!",
NO_CARET);
xdiff = (x_max - x_min) / mysamples;
tp_ptr = &(first_plot);
plot_num = 0;
while (TRUE) {
if (END_OF_COMMAND)
int_error("function to plot expected",c_token);
start_token = c_token;
if (is_definition(c_token)) {
define();
} else {
plot_num++;
if (*tp_ptr)
this_plot = *tp_ptr;
else { /* no memory malloc()'d there yet */
this_plot = (struct curve_points *)
malloc((unsigned int) (sizeof(struct curve_points) -
(MAX_POINTS - (samples+1))*sizeof(struct coordinate)));
if (!this_plot)
int_error("out of memory",c_token);
this_plot->next_cp = NULL;
this_plot->title = NULL;
*tp_ptr = this_plot;
}
if (isstring(c_token)) { /* data file to plot */
this_plot->plot_type = DATA;
this_plot->plot_style = data_style;
get_data(this_plot);
c_token++;
}
else { /* function to plot */
this_plot->plot_type = FUNC;
this_plot->plot_style = func_style;
(void) strcpy(c_dummy_var,dummy_var);
dummy_func = &plot_func;
plot_func.at = temp_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(&plot_func.dummy_value, x, 0.0);
evaluate_at(plot_func.at,&a);
if (this_plot->points[i].undefined =
undefined || (fabs(imag(&a)) > zero))
continue;
temp = real(&a);
if (log_y && temp <= 0.0) {
this_plot->points[i].undefined = TRUE;
continue;
}
if (autoscale) {
if (temp < ymin) ymin = temp;
if (temp > ymax) ymax = temp;
} else if (temp < ymin || temp > ymax) {
this_plot->points[i].undefined = TRUE;
continue;
}
this_plot->points[i].y = log_y ? log10(temp) : temp;
}
this_plot->p_count = i; /* mysamples + 1 */
}
m_capture(&(this_plot->title),start_token,c_token-1);
if (almost_equals(c_token,"w$ith"))
this_plot->plot_style = get_style();
tp_ptr = &(this_plot->next_cp);
}
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;
}
capture(replot_line,plot_token,c_token);
do_plot(first_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
#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(help_desc,help);
$DESCRIPTOR(helpfile_desc,"GNUPLOT$HELP");
read_line()
{
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 */
}
input_line[vms_len] = '\0';
}
do_help()
{
help_desc.dsc$w_length = strlen(help);
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");
}
do_shell()
{
if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
os_error("spawn error",NO_CARET);
}
}
do_system()
{
input_line[0] = ' '; /* an embarrassment, but... */
if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
os_error("spawn error",NO_CARET);
(void) putc('\n',stderr);
}
#else /* vms */
do_help()
{
if (system(help))
os_error("can't spawn help",c_token);
}
do_system()
{
if (system(input_line + 1))
os_error("system() failed",NO_CARET);
}
#ifdef MSDOS
read_line()
{
register int i;
input_line[0] = MAX_LINE_LEN - 1;
cputs(PROMPT);
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);
}
i = 0;
while (input_line[i] = input_line[i+2])
i++; /* yuck! move everything down two characters */
}
do_shell()
{
register char *comspec;
if (!(comspec = getenv("COMSPEC")))
comspec = "\command.com";
if (spawnl(P_WAIT,comspec,NULL) == -1)
os_error("unable to spawn shell",NO_CARET);
}
#else /* MSDOS */
/* plain old Unix */
read_line()
{
fputs(PROMPT,stderr);
if (!gets(input_line)) {
(void) putc('\n',stderr); /* end-of-file */
done(IO_SUCCESS);
}
}
#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(strncpy(&exec[sizeof(EXEC)-1],shell,
sizeof(exec)-sizeof(EXEC)-1)))
os_error("system() failed",NO_CARET);
(void) putc('\n',stderr);
}
#endif /* VFORK */
#endif /* MSDOS */
#endif /* vms */
SHAR_EOF
if test 21346 -ne "`wc -c < 'command.c'`"
then
echo shar: error transmitting "'command.c'" '(should have been 21346 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'eval.c'" '(3101 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, 1987 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"
char *malloc();
extern int c_token;
extern struct ft_entry ft[];
extern struct udvt_entry *first_udv;
extern struct udft_entry *first_udf;
extern struct at_type at;
extern struct lexical_unit token[];
struct value *integer();
struct udvt_entry *
add_udv(t_num) /* find or add value and return pointer */
int t_num;
{
register struct udvt_entry **udv_ptr = &first_udv;
/* check if it's already in the table... */
while (*udv_ptr) {
if (equals(t_num,(*udv_ptr)->udv_name))
return(*udv_ptr);
udv_ptr = &((*udv_ptr)->next_udv);
}
if (!(*udv_ptr = (struct udvt_entry *)
malloc((unsigned int)sizeof(struct udvt_entry))))
int_error("not enought memory for value",t_num);
(*udv_ptr)->next_udv = NULL;
copy_str((*udv_ptr)->udv_name,t_num);
(*udv_ptr)->udv_value.type = INT; /* not necessary, but safe! */
(*udv_ptr)->udv_undef = TRUE;
return(*udv_ptr);
}
struct udft_entry *
add_udf(t_num) /* find or add function and return pointer */
int t_num; /* index to token[] */
{
register struct udft_entry **udf_ptr = &first_udf;
while (*udf_ptr) {
if (equals(t_num,(*udf_ptr)->udf_name))
return(*udf_ptr);
udf_ptr = &((*udf_ptr)->next_udf);
}
if (!(*udf_ptr = (struct udft_entry *)
malloc((unsigned int)sizeof(struct udft_entry))))
int_error("not enought memory for function",t_num);
(*udf_ptr)->next_udf = (struct udft_entry *) NULL;
(*udf_ptr)->definition = NULL;
(*udf_ptr)->at = NULL;
copy_str((*udf_ptr)->udf_name,t_num);
(void) integer(&((*udf_ptr)->dummy_value), 0);
return(*udf_ptr);
}
union argument *
add_action(sf_index)
enum operators sf_index; /* index of p-code function */
{
if (at.a_count >= MAX_AT_LEN)
int_error("action table overflow",NO_CARET);
at.actions[at.a_count].index = sf_index;
return(&(at.actions[at.a_count++].arg));
}
int standard(t_num) /* return standard function index or 0 */
{
register int i;
for (i = (int)SF_START; ft[i].f_name != NULL; i++) {
if (equals(t_num,ft[i].f_name))
return(i);
}
return(0);
}
execute_at(at_ptr)
struct at_type *at_ptr;
{
register int i,index,count,offset;
count = at_ptr->a_count;
for (i = 0; i < count;) {
index = (int)at_ptr->actions[i].index;
offset = (*ft[index].func)(&(at_ptr->actions[i].arg));
if (is_jump(index))
i += offset;
else
i++;
}
}
/*
'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 address of the argument which is pointed to by the arg_ptr
*/
SHAR_EOF
if test 3101 -ne "`wc -c < 'eval.c'`"
then
echo shar: error transmitting "'eval.c'" '(should have been 3101 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'graphics.c'" '(7287 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, 1987 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;
{
register 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)
char *a,b;
{
do {
if (*a == b)
return(a);
} while (*a++);
return(0);
}
num2str(num,str)
double num;
char str[];
{
static char temp[80];
register double d;
register char *a,*b;
if ((d = fabs(num)) > 9999.0 || d < 0.001 && d != 0.0)
(void) sprintf(temp,"%-.3e",num);
else
(void) sprintf(temp,"%-.3g",num);
if (b = idx(temp,'e')) {
a = b;
while ( *(--a) == '0') /* trailing zeros */
;
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' */
(void) strcat(str,"e");
if ( *a == '-')
(void) strcat(str,"-");
a++; /* advance a past '+' or '-' */
while ( *a == '0' && *(a+1) != '\0') /* leading zeroes */
a++;
(void) strcat(str,a); /* copy rest of string */
}
else
(void) strcpy(str,temp);
}
do_plot(plots, pcount, xmin, xmax, ymin, ymax)
struct curve_points *plots;
int pcount; /* count of plots in linked list */
double xmin, xmax;
double ymin, ymax;
{
register int i, x;
register struct termentry *t = &term_tbl[term];
register BOOLEAN prev_undef;
register int curve, xaxis_y, yaxis_x, dpcount;
register struct curve_points *this_plot;
register enum PLOT_TYPE p_type;
register double xscale, yscale;
register double ytic, xtic, least, most, ticplace;
register int mms,mts;
/* only a Pyramid would have this many registers! */
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);
dpcount = 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 */
this_plot = plots;
for (curve = 0; curve < pcount; this_plot = this_plot->next_cp, curve++) {
(*t->linetype)(curve);
(*t->ulput_text)(curve, this_plot->title);
(*t->linetype)(curve);
p_type = this_plot->plot_type;
switch(this_plot->plot_style) {
case IMPULSES:
for (i = 0; i < this_plot->p_count; i++) {
if (!this_plot->points[i].undefined) {
if (p_type == DATA)
x = map_x(this_plot->points[i].x);
else
x = (long)(t->xmax-1)*i/(this_plot->p_count-1);
(*t->move)(x,xaxis_y);
(*t->vector)(x,map_y(this_plot->points[i].y));
}
}
break;
case LINES:
prev_undef = TRUE;
for (i = 0; i < this_plot->p_count; i++) {
if (!this_plot->points[i].undefined) {
if (p_type == DATA)
x = map_x(this_plot->points[i].x);
else
x = (long)(t->xmax-1)*i/(this_plot->p_count-1);
if (prev_undef)
(*t->move)(x,
map_y(this_plot->points[i].y));
(*t->vector)(x,
map_y(this_plot->points[i].y));
}
prev_undef = this_plot->points[i].undefined;
}
break;
case POINTS:
for (i = 0; i < this_plot->p_count; i++) {
if (!this_plot->points[i].undefined) {
if (p_type == DATA)
x = map_x(this_plot->points[i].x);
else
x = (long)(t->xmax-1)*i/(this_plot->p_count-1);
(*t->point)(x,map_y(this_plot->points[i].y),dpcount);
}
}
dpcount++;
break;
}
}
(*t->text)();
(void) fflush(outfile);
}
SHAR_EOF
if test 7287 -ne "`wc -c < 'graphics.c'`"
then
echo shar: error transmitting "'graphics.c'" '(should have been 7287 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'internal.c'" '(13595 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, 1987 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;
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);
}
push(x)
struct value *x;
{
if (s_p == STACK_DEPTH - 1)
int_error("stack overflow",NO_CARET);
stack[++s_p] = *x;
}
#define ERR_VAR "undefined variable: "
f_push(x)
union argument *x; /* contains pointer to value to push; */
{
static char err_str[sizeof(ERR_VAR) + MAX_ID_LEN] = ERR_VAR;
struct udvt_entry *udv;
udv = x->udv_arg;
if (udv->udv_undef) { /* undefined */
(void) strcpy(&err_str[sizeof(ERR_VAR) - 1], udv->udv_name);
int_error(err_str,NO_CARET);
}
push(&(udv->udv_value));
}
f_pushc(x)
union argument *x;
{
push(&(x->v_arg));
}
f_pushd(x)
union argument *x;
{
push(&(x->udf_arg->dummy_value));
}
#define ERR_FUN "undefined function: "
f_call(x) /* execute a udf */
union argument *x;
{
static char err_str[sizeof(ERR_FUN) + MAX_ID_LEN] = ERR_FUN;
register struct udft_entry *udf;
udf = x->udf_arg;
if (!udf->at) { /* undefined */
(void) strcpy(&err_str[sizeof(ERR_FUN) - 1],
udf->udf_name);
int_error(err_str,NO_CARET);
}
(void) pop(&(udf->dummy_value));
execute_at(udf->at);
}
static int_check(v)
struct value *v;
{
if (v->type != INT)
int_error("non-integer passed to boolean operator",NO_CARET);
}
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_bool()
{ /* converts top-of-stack to boolean */
int_check(&top_of_stack);
top_of_stack.v.int_val = !!top_of_stack.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:
if (a.v.cmplx_val.imag == 0.0) {
mag = pow(a.v.cmplx_val.real,(double)abs(b.v.int_val));
if (b.v.int_val < 0)
mag = 1.0/mag;
(void) complex(&result,mag,0.0);
}
else {
/* 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);
}
f_factorial()
{
struct value a;
register int i;
register double val;
(void) pop(&a); /* find a! (factorial) */
switch (a.type) {
case INT:
val = 1.0;
for (i = a.v.int_val; i > 1; i--) /*fpe's should catch overflows*/
val *= i;
break;
default:
int_error("factorial (!) argument must be an integer",
NO_CARET);
}
push(complex(&a,val,0.0));
}
int
f_jump(x)
union argument *x;
{
return(x->j_arg);
}
int
f_jumpz(x)
union argument *x;
{
struct value a;
int_check(&top_of_stack);
if (top_of_stack.v.int_val) { /* non-zero */
(void) pop(&a);
return 1; /* no jump */
}
else
return(x->j_arg); /* leave the argument on TOS */
}
int
f_jumpnz(x)
union argument *x;
{
struct value a;
int_check(&top_of_stack);
if (top_of_stack.v.int_val) /* non-zero */
return(x->j_arg); /* leave the argument on TOS */
else {
(void) pop(&a);
return 1; /* no jump */
}
}
int
f_jtern(x)
union argument *x;
{
struct value a;
int_check(pop(&a));
if (a.v.int_val)
return(1); /* no jump; fall through to TRUE code */
else
return(x->j_arg); /* go jump to FALSE code */
}
SHAR_EOF
if test 13595 -ne "`wc -c < 'internal.c'`"
then
echo shar: error transmitting "'internal.c'" '(should have been 13595 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'misc.c'" '(5921 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, 1987 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 autoscale;
extern BOOLEAN log_x, log_y;
extern FILE* outfile;
extern char outstr[];
extern int samples;
extern int term;
extern double zero;
extern BOOLEAN screen_ok;
extern int c_token;
extern struct at_type at;
extern struct ft_entry ft[];
extern struct udft_entry *first_udf;
extern struct udvt_entry *first_udv;
extern struct termentry term_tbl[];
char *malloc();
struct at_type *temp_at();
/*
* cp_free() releases any memory which was previously malloc()'d to hold
* curve points.
*/
cp_free(cp)
struct curve_points *cp;
{
if (cp) {
cp_free(cp->next_cp);
if (cp->title)
free((char *)cp->title);
free((char *)cp);
}
}
save_functions(fp)
FILE *fp;
{
register struct udft_entry *udf = first_udf;
if (fp) {
while (udf) {
if (udf->definition)
fprintf(fp,"%s\n",udf->definition);
udf = udf->next_udf;
}
(void) fclose(fp);
} else
os_error("Cannot open save file",c_token);
}
save_variables(fp)
FILE *fp;
{
register struct udvt_entry *udv = first_udv->next_udv; /* skip pi */
if (fp) {
while (udv) {
if (!udv->udv_undef) {
fprintf(fp,"%s = ",udv->udv_name);
disp_value(fp,&(udv->udv_value));
(void) putc('\n',fp);
}
udv = udv->next_udv;
}
(void) fclose(fp);
} else
os_error("Cannot open save file",c_token);
}
save_all(fp)
FILE *fp;
{
register struct udft_entry *udf = first_udf;
register struct udvt_entry *udv = first_udv->next_udv; /* skip pi */
if (fp) {
while (udf) {
if (udf->definition)
fprintf(fp,"%s\n",udf->definition);
udf = udf->next_udf;
}
while (udv) {
if (!udv->udv_undef) {
fprintf(fp,"%s = ",udv->udv_name);
disp_value(fp,&(udv->udv_value));
(void) putc('\n',fp);
}
udv = udv->next_udv;
}
(void) fclose(fp);
} else
os_error("Cannot open save file",c_token);
}
load_file(fp)
FILE *fp;
{
register int len;
extern char input_line[];
if (fp) {
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);
} else
os_error("Cannot open load file",c_token);
}
show_style(name,style)
char name[];
enum PLOT_STYLE style;
{
fprintf(stderr,"\t%s are plotted with ",name);
switch (style) {
case LINES: fprintf(stderr,"lines\n"); break;
case POINTS: fprintf(stderr,"points\n"); break;
case IMPULSES: fprintf(stderr,"impulses\n"); break;
}
}
show_range(name,min,max)
char name;
double min,max;
{
fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
}
show_zero()
{
fprintf(stderr,"\tzero is %g\n",zero);
}
show_samples()
{
fprintf(stderr,"\tsampling rate is %d\n",samples);
}
show_output()
{
fprintf(stderr,"\toutput is sent to %s\n",outstr);
}
show_term()
{
fprintf(stderr,"\tterminal type is %s\n",term_tbl[term].name);
}
show_autoscale()
{
fprintf(stderr,"\tautoscaling is %s\n",(autoscale)? "ON" : "OFF");
}
show_logscale()
{
if (log_x && log_y)
fprintf(stderr,"\tlogscaling both x and y axes\n");
else if (log_x)
fprintf(stderr,"\tlogscaling x axis\n");
else if (log_y)
fprintf(stderr,"\tlogscaling y axis\n");
else
fprintf(stderr,"\tno logscaling\n");
}
show_variables()
{
register struct udvt_entry *udv = first_udv;
fprintf(stderr,"\n\tVariables:\n");
while (udv) {
fprintf(stderr,"\t%-*s ",MAX_ID_LEN,udv->udv_name);
if (udv->udv_undef)
fputs("is undefined\n",stderr);
else {
fputs("= ",stderr);
disp_value(stderr,&(udv->udv_value));
(void) putc('\n',stderr);
}
udv = udv->next_udv;
}
}
show_functions()
{
register struct udft_entry *udf = first_udf;
fprintf(stderr,"\n\tUser-Defined Functions:\n");
while (udf) {
if (udf->definition)
fprintf(stderr,"\t%s\n",udf->definition);
else
fprintf(stderr,"\t%s is undefined\n",udf->udf_name);
udf = udf->next_udf;
}
}
show_at()
{
(void) putc('\n',stderr);
disp_at(temp_at(),0);
}
disp_at(curr_at, level)
struct at_type *curr_at;
int level;
{
register int i, j;
register union argument *arg;
for (i = 0; i < curr_at->a_count; i++) {
(void) putc('\t',stderr);
for (j = 0; j < level; j++)
(void) putc(' ',stderr); /* indent */
/* print name of instruction */
fputs(ft[(int)(curr_at->actions[i].index)].f_name,stderr);
arg = &(curr_at->actions[i].arg);
/* now print optional argument */
switch(curr_at->actions[i].index) {
case PUSH: fprintf(stderr," %s\n", arg->udv_arg->udv_name);
break;
case PUSHC: (void) putc(' ',stderr);
disp_value(stderr,&(arg->v_arg));
(void) putc('\n',stderr);
break;
case PUSHD: fprintf(stderr," %s dummy\n",
arg->udf_arg->udf_name);
break;
case CALL: fprintf(stderr," %s", arg->udf_arg->udf_name);
if (arg->udf_arg->at) {
(void) putc('\n',stderr);
disp_at(arg->udf_arg->at,level+2); /* recurse! */
} else
fputs(" (undefined)\n",stderr);
break;
case JUMP:
case JUMPZ:
case JUMPNZ:
case JTERN:
fprintf(stderr," +%d\n",arg->j_arg);
break;
default:
(void) putc('\n',stderr);
}
}
}
show_version()
{
extern char version[];
extern char date[];
static char *authors[] = {"Thomas Williams","Colin Kelley"};
int x;
long time();
x = time((long *)NULL) & 1;
fprintf(stderr,"\n\t%s\n\t%sversion %s\n\tlast modified %s\n",
PROGRAM, OS, version, date);
fprintf(stderr,"\tCopyright (C) 1986, 1987 %s, %s\n\n",
authors[x],authors[1-x]);
}
SHAR_EOF
if test 5921 -ne "`wc -c < 'misc.c'`"
then
echo shar: error transmitting "'misc.c'" '(should have been 5921 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'parse.c'" '(7780 characters)'
if test -f 'parse.c'
then
echo shar: will not over-write existing file "'parse.c'"
else
cat << \SHAR_EOF > 'parse.c'
/*
*
* G N U P L O T -- parse.c
*
* Copyright (C) 1986, 1987 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 <setjmp.h>
#include <signal.h>
#include <errno.h>
#include "plot.h"
extern BOOLEAN undefined;
#ifndef vms
extern int errno;
#endif
extern int num_tokens,c_token;
extern struct lexical_unit token[];
extern char c_dummy_var[]; /* name of current dummy variable */
extern struct udft_entry *dummy_func; /* pointer to dummy variable's func */
char *malloc();
struct value *pop(),*integer(),*complex();
struct at_type *temp_at(), *perm_at();
struct udft_entry *add_udf();
struct udvt_entry *add_udv();
union argument *add_action();
struct at_type at;
static jmp_buf fpe_env;
#define dummy (struct value *) 0
fpe()
{
#ifdef PC /* thanks to lotto at wjh12.UUCP for telling us about this */
_fpreset();
#endif
(void) signal(SIGFPE, fpe);
undefined = TRUE;
longjmp(fpe_env, TRUE);
}
evaluate_at(at_ptr,val_ptr)
struct at_type *at_ptr;
struct value *val_ptr;
{
undefined = FALSE;
errno = 0;
reset_stack();
if (setjmp(fpe_env))
return; /* just bail out */
(void) signal(SIGFPE, fpe); /* catch core dumps on FPEs */
execute_at(at_ptr);
(void) signal(SIGFPE, SIG_DFL);
if (errno == EDOM || errno == ERANGE) {
undefined = TRUE;
} else {
(void) pop(val_ptr);
check_stack();
}
}
struct value *
const_express(valptr)
struct value *valptr;
{
register int tkn = c_token;
if (END_OF_COMMAND)
int_error("constant expression required",c_token);
evaluate_at(temp_at(),valptr); /* run it and send answer back */
if (undefined) {
int_error("undefined value",tkn);
}
return(valptr);
}
struct at_type *
temp_at() /* build a static action table and return its pointer */
{
at.a_count = 0; /* reset action table !!! */
express();
return(&at);
}
/* build an action table, put it in dynamic memory, and return its pointer */
struct at_type *
perm_at()
{
register struct at_type *at_ptr;
register unsigned int len;
(void) temp_at();
len = sizeof(struct at_type) -
(MAX_AT_LEN - at.a_count)*sizeof(struct at_entry);
if (at_ptr = (struct at_type *) malloc(len))
(void) memcpy(at_ptr,&at,len);
return(at_ptr);
}
#ifdef NOCOPY
/*
* cheap and slow version of memcpy() in case you don't have one
*/
memcpy(dest,src,len)
char *dest,*src;
unsigned int len;
{
while (len--)
*dest++ = *src++;
}
#endif /* NOCOPY */
express() /* full expressions */
{
xterm();
xterms();
}
xterm() /* ? : expressions */
{
aterm();
aterms();
}
aterm()
{
bterm();
bterms();
}
bterm()
{
cterm();
cterms();
}
cterm()
{
dterm();
dterms();
}
dterm()
{
eterm();
eterms();
}
eterm()
{
fterm();
fterms();
}
fterm()
{
gterm();
gterms();
}
gterm()
{
hterm();
hterms();
}
hterm()
{
unary(); /* - things */
iterms(); /* * / % */
}
factor()
{
register int value;
if (equals(c_token,"(")) {
c_token++;
express();
if (!equals(c_token,")"))
int_error("')' expected",c_token);
c_token++;
}
else if (isnumber(c_token)) {
convert(&(add_action(PUSHC)->v_arg),c_token);
c_token++;
}
else if (isletter(c_token)) {
if ((c_token+1 < num_tokens) && equals(c_token+1,"(")) {
value = standard(c_token);
if (value) { /* it's a standard function */
c_token += 2;
express();
if (!equals(c_token,")"))
int_error("')' expected",c_token);
c_token++;
(void) add_action(value);
}
else {
value = c_token;
c_token += 2;
express();
if (!equals(c_token,")"))
int_error("')' expected",c_token);
c_token++;
add_action(CALL)->udf_arg = add_udf(value);
}
}
else {
if (equals(c_token,c_dummy_var)) {
c_token++;
add_action(PUSHD)->udf_arg = dummy_func;
}
else {
add_action(PUSH)->udv_arg = add_udv(c_token);
c_token++;
}
}
} /* end if letter */
else
int_error("invalid expression ",c_token);
/* add action code for ! (factorial) operator */
while (equals(c_token,"!")) {
c_token++;
(void) add_action(FACTORIAL);
}
/* add action code for ** operator */
if (equals(c_token,"**")) {
c_token++;
unary();
(void) add_action(POWER);
}
}
xterms()
{ /* create action code for ? : expressions */
if (equals(c_token,"?")) {
register int savepc1, savepc2;
register union argument *argptr1,*argptr2;
c_token++;
savepc1 = at.a_count;
argptr1 = add_action(JTERN);
express();
if (!equals(c_token,":"))
int_error("expecting ':'",c_token);
c_token++;
savepc2 = at.a_count;
argptr2 = add_action(JUMP);
argptr1->j_arg = at.a_count - savepc1;
express();
argptr2->j_arg = at.a_count - savepc2;
}
}
aterms()
{ /* create action codes for || operator */
while (equals(c_token,"||")) {
register int savepc;
register union argument *argptr;
c_token++;
savepc = at.a_count;
argptr = add_action(JUMPNZ); /* short-circuit if already TRUE */
aterm();
argptr->j_arg = at.a_count - savepc;/* offset for jump */
(void) add_action(BOOL);
}
}
bterms()
{ /* create action code for && operator */
while (equals(c_token,"&&")) {
register int savepc;
register union argument *argptr;
c_token++;
savepc = at.a_count;
argptr = add_action(JUMPZ); /* short-circuit if already FALSE */
bterm();
argptr->j_arg = at.a_count - savepc;/* offset for jump */
(void) add_action(BOOL);
}
}
cterms()
{ /* create action code for | operator */
while (equals(c_token,"|")) {
c_token++;
cterm();
(void) add_action(BOR);
}
}
dterms()
{ /* create action code for ^ operator */
while (equals(c_token,"^")) {
c_token++;
dterm();
(void) add_action(XOR);
}
}
eterms()
{ /* create action code for & operator */
while (equals(c_token,"&")) {
c_token++;
eterm();
(void) add_action(BAND);
}
}
fterms()
{ /* create action codes for == and != operators */
while (TRUE) {
if (equals(c_token,"==")) {
c_token++;
fterm();
(void) add_action(EQ);
}
else if (equals(c_token,"!=")) {
c_token++;
fterm();
(void) add_action(NE);
}
else break;
}
}
gterms()
{ /* create action code for < > >= or <= operators */
while (TRUE) {
/* I hate "else if" statements */
if (equals(c_token,">")) {
c_token++;
gterm();
(void) add_action(GT);
}
else if (equals(c_token,"<")) {
c_token++;
gterm();
(void) add_action(LT);
}
else if (equals(c_token,">=")) {
c_token++;
gterm();
(void) add_action(GE);
}
else if (equals(c_token,"<=")) {
c_token++;
gterm();
(void) add_action(LE);
}
else break;
}
}
hterms()
{ /* create action codes for + and - operators */
while (TRUE) {
if (equals(c_token,"+")) {
c_token++;
hterm();
(void) add_action(PLUS);
}
else if (equals(c_token,"-")) {
c_token++;
hterm();
(void) add_action(MINUS);
}
else break;
}
}
iterms()
{ /* add action code for * / and % operators */
while (TRUE) {
if (equals(c_token,"*")) {
c_token++;
unary();
(void) add_action(MULT);
}
else if (equals(c_token,"/")) {
c_token++;
unary();
(void) add_action(DIV);
}
else if (equals(c_token,"%")) {
c_token++;
unary();
(void) add_action(MOD);
}
else break;
}
}
unary()
{ /* add code for unary operators */
if (equals(c_token,"!")) {
c_token++;
unary();
(void) add_action(LNOT);
}
else if (equals(c_token,"~")) {
c_token++;
unary();
(void) add_action(BNOT);
}
else if (equals(c_token,"-")) {
c_token++;
unary();
(void) add_action(UMINUS);
}
else
factor();
}
SHAR_EOF
if test 7780 -ne "`wc -c < 'parse.c'`"
then
echo shar: error transmitting "'parse.c'" '(should have been 7780 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Comp.sources.unix
mailing list