williams@vu-vlsi.UUCP (01/28/87)
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@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