Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!columbia!rutgers!cbmvax!vu-vlsi!taw From: taw@vu-vlsi.UUCP (Thomas Williams) Newsgroups: net.sources Subject: GNUPLOT (1 of 4) Message-ID: <429@vu-vlsi.UUCP> Date: Mon, 17-Nov-86 19:32:56 EST Article-I.D.: vu-vlsi.429 Posted: Mon Nov 17 19:32:56 1986 Date-Received: Tue, 18-Nov-86 21:50:32 EST Organization: Villanova Univ. EE Dept. Lines: 2324 Keywords: plotting 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 #include #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 */ 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 #endif /* MSDOS */ #ifdef vms #include #include #include 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 #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 #include #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 #include #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 #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