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