home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume24
/
gnuplot3
/
part02
< prev
next >
Wrap
Text File
|
1991-10-26
|
49KB
|
1,955 lines
Newsgroups: comp.sources.misc
From: gershon%gr@cs.utah.edu (Elber Gershon)
Subject: v24i024: gnuplot3 - interactive function plotting utility, Part02/26
Message-ID: <1991Oct26.222043.6126@sparky.imd.sterling.com>
X-Md4-Signature: 8c80eabd38766e4977b7667f9127fd45
Date: Sat, 26 Oct 1991 22:20:43 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
Posting-number: Volume 24, Issue 24
Archive-name: gnuplot3/part02
Environment: UNIX, MS-DOS, VMS
Supersedes: gnuplot2: Volume 11, Issue 65-79
#!/bin/sh
# this is Part.02 (part 2 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file gnuplot/setshow.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 2; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test ! -f _shar_wnt_.tmp; then
echo 'x - still skipping gnuplot/setshow.c'
else
echo 'x - continuing file gnuplot/setshow.c'
sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/setshow.c' &&
X prev_arrow = this_arrow, this_arrow = this_arrow->next) {
X if (this_arrow->tag == tag) {
X delete_arrow(prev_arrow,this_arrow);
X return; /* exit, our job is done */
X }
X }
X int_error("arrow not found", c_token);
X }
}
X
/* assign a new arrow tag */
/* arrows are kept sorted by tag number, so this is easy */
static int /* the lowest unassigned tag number */
assign_arrow_tag()
{
X struct arrow_def *this_arrow;
X int last = 0; /* previous tag value */
X
X for (this_arrow = first_arrow; this_arrow != NULL;
X this_arrow = this_arrow->next)
X if (this_arrow->tag == last+1)
X last++;
X else
X break;
X
X return (last+1);
}
X
/* delete arrow from linked list started by first_arrow.
X * called with pointers to the previous arrow (prev) and the
X * arrow to delete (this).
X * If there is no previous arrow (the arrow to delete is
X * first_arrow) then call with prev = NULL.
X */
static void
delete_arrow(prev,this)
X struct arrow_def *prev, *this;
{
X if (this!=NULL) { /* there really is something to delete */
X if (prev!=NULL) /* there is a previous arrow */
X prev->next = this->next;
X else /* this = first_arrow so change first_arrow */
X first_arrow = this->next;
X free((char *)this);
X }
}
X
X
enum PLOT_STYLE /* not static; used by command.c */
get_style()
{
register enum PLOT_STYLE ps;
X
X c_token++;
X if (almost_equals(c_token,"l$ines"))
X ps = LINES;
X else if (almost_equals(c_token,"i$mpulses"))
X ps = IMPULSES;
X else if (almost_equals(c_token,"p$oints"))
X ps = POINTS;
X else if (almost_equals(c_token,"linesp$oints"))
X ps = LINESPOINTS;
X else if (almost_equals(c_token,"d$ots"))
X ps = DOTS;
X else if (almost_equals(c_token,"e$rrorbars"))
X ps = ERRORBARS;
X else
X int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', or 'errorbars'",c_token);
X c_token++;
X return(ps);
}
X
/* For set [xy]tics... command*/
static void
load_tics(tdef)
X struct ticdef *tdef; /* change this ticdef */
{
X if (equals(c_token,"(")) { /* set : TIC_USER */
X c_token++;
X load_tic_user(tdef);
X } else { /* series : TIC_SERIES */
X load_tic_series(tdef);
X }
}
X
/* load TIC_USER definition */
/* (tic[,tic]...)
X * where tic is ["string"] value
X * Left paren is already scanned off before entry.
X */
static void
load_tic_user(tdef)
X struct ticdef *tdef;
{
X struct ticmark *list = NULL; /* start of list */
X struct ticmark *last = NULL; /* end of list */
X struct ticmark *tic = NULL; /* new ticmark */
X char temp_string[MAX_LINE_LEN];
X struct value a;
X
X while (!END_OF_COMMAND) {
X /* parse a new ticmark */
X tic = (struct ticmark *)alloc(sizeof(struct ticmark), (char *)NULL);
X if (tic == (struct ticmark *)NULL) {
X free_marklist(list);
X int_error("out of memory for tic mark", c_token);
X }
X
X /* has a string with it? */
X if (isstring(c_token)) {
X quote_str(temp_string,c_token);
X tic->label = alloc((unsigned int)strlen(temp_string)+1, "tic label");
X (void) strcpy(tic->label, temp_string);
X c_token++;
X } else
X tic->label = NULL;
X
X /* in any case get the value */
X tic->position = real(const_express(&a));
X tic->next = NULL;
X
X /* append to list */
X if (list == NULL)
X last = list = tic; /* new list */
X else { /* append to list */
X last->next = tic;
X last = tic;
X }
X
X /* expect "," or ")" here */
X if (!END_OF_COMMAND && equals(c_token, ","))
X c_token++; /* loop again */
X else
X break; /* hopefully ")" */
X }
X
X if (END_OF_COMMAND || !equals(c_token, ")")) {
X free_marklist(list);
X int_error("expecting right parenthesis )", c_token);
X }
X c_token++;
X
X /* successful list */
X if (tdef->type == TIC_USER) {
X /* remove old list */
X /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
X free_marklist(tdef->def.user);
X tdef->def.user = NULL;
X }
X tdef->type = TIC_USER;
X tdef->def.user = list;
}
X
static void
free_marklist(list)
X struct ticmark *list;
{
X register struct ticmark *freeable;
X
X while (list != NULL) {
X freeable = list;
X list = list->next;
X if (freeable->label != NULL)
X free( (char *)freeable->label );
X free( (char *)freeable );
X }
}
X
/* load TIC_SERIES definition */
/* start,incr[,end] */
static void
load_tic_series(tdef)
X struct ticdef *tdef;
{
X double start, incr, end;
X struct value a;
X int incr_token;
X
X start = real(const_express(&a));
X if (!equals(c_token, ","))
X int_error("expecting comma to separate start,incr", c_token);
X c_token++;
X
X incr_token = c_token;
X incr = real(const_express(&a));
X
X if (END_OF_COMMAND)
X end = VERYLARGE;
X else {
X if (!equals(c_token, ","))
X int_error("expecting comma to separate incr,end", c_token);
X c_token++;
X
X end = real(const_express(&a));
X }
X if (!END_OF_COMMAND)
X int_error("tic series is defined by start,increment[,end]",
X c_token);
X
X if (start < end && incr <= 0)
X int_error("increment must be positive", incr_token);
X if (start > end && incr >= 0)
X int_error("increment must be negative", incr_token);
X if (start > end) {
X /* put in order */
X double numtics;
X numtics = floor( (end*(1+SIGNIF) - start)/incr );
X end = start;
X start = end + numtics*incr;
X incr = -incr;
/*
X double temp = start;
X start = end;
X end = temp;
X incr = -incr;
X */
X }
X
X if (tdef->type == TIC_USER) {
X /* remove old list */
X /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
X free_marklist(tdef->def.user);
X tdef->def.user = NULL;
X }
X tdef->type = TIC_SERIES;
X tdef->def.series.start = start;
X tdef->def.series.incr = incr;
X tdef->def.series.end = end;
}
X
static void
load_offsets (a, b, c, d)
double *a,*b, *c, *d;
{
struct value t;
X
X *a = real (const_express(&t)); /* loff value */
X c_token++;
X if (equals(c_token,","))
X c_token++;
X if (END_OF_COMMAND)
X return;
X
X *b = real (const_express(&t)); /* roff value */
X c_token++;
X if (equals(c_token,","))
X c_token++;
X if (END_OF_COMMAND)
X return;
X
X *c = real (const_express(&t)); /* toff value */
X c_token++;
X if (equals(c_token,","))
X c_token++;
X if (END_OF_COMMAND)
X return;
X
X *d = real (const_express(&t)); /* boff value */
X c_token++;
}
X
X
BOOLEAN /* TRUE if a or b were changed */
load_range(a,b) /* also used by command.c */
double *a,*b;
{
struct value t;
BOOLEAN changed = FALSE;
X
X if (equals(c_token,"]"))
X return(FALSE);
X if (END_OF_COMMAND) {
X int_error("starting range value or ':' or 'to' expected",c_token);
X } else if (!equals(c_token,"to") && !equals(c_token,":")) {
X *a = real(const_express(&t));
X changed = TRUE;
X }
X if (!equals(c_token,"to") && !equals(c_token,":"))
X int_error("':' or keyword 'to' expected",c_token);
X c_token++;
X if (!equals(c_token,"]")) {
X *b = real(const_express(&t));
X changed = TRUE;
X }
X return(changed);
}
X
X
X
/******* The 'show' command *******/
void
show_command()
{
X c_token++;
X
X if (!show_one() && !show_two())
X int_error(
X "valid show options: 'action_table', 'all', 'angles', 'arrow', \n\
X 'autoscale', 'border', 'clip', 'contour', 'data', 'dummy', 'format', \n\
X 'function', 'grid', 'key', 'label', 'logscale', 'mapping', 'offsets', \n\
X 'output', 'plot', 'parametric', 'polar', 'rrange', 'samples', \n\
X 'isosamples', 'view', 'size', 'terminal', 'tics', 'ticslevel', \n\
X 'time', 'title', 'trange', 'urange', 'vrange', 'variables', \n\
X 'version', 'xlabel', 'xrange', 'xtics', 'xzeroaxis', 'ylabel', \n\
X 'yrange', 'ytics', 'yzeroaxis', 'zlabel', 'zrange', 'ztics', 'zero', \n\
X 'zeroaxis'", c_token);
X screen_ok = FALSE;
X (void) putc('\n',stderr);
}
X
/* return TRUE if a command match, FALSE if not */
static BOOLEAN
show_one()
{
X if (almost_equals(c_token,"ac$tion_table") ||
X equals(c_token,"at") ) {
X c_token++;
X show_at();
X c_token++;
X }
X else if (almost_equals(c_token,"ar$row")) {
X struct value a;
X int tag = 0;
X
X c_token++;
X if (!END_OF_COMMAND) {
X tag = (int)real(const_express(&a));
X if (tag <= 0)
X int_error("tag must be > zero", c_token);
X }
X
X (void) putc('\n',stderr);
X show_arrow(tag);
X }
X else if (almost_equals(c_token,"au$toscale")) {
X (void) putc('\n',stderr);
X show_autoscale();
X c_token++;
X }
X else if (almost_equals(c_token,"bor$der")) {
X (void) putc('\n',stderr);
X show_border();
X c_token++;
X }
X else if (almost_equals(c_token,"c$lip")) {
X (void) putc('\n',stderr);
X show_clip();
X c_token++;
X }
X else if (almost_equals(c_token,"ma$pping")) {
X (void) putc('\n',stderr);
X show_mapping();
X c_token++;
X }
X else if (almost_equals(c_token,"co$ntour")) {
X (void) putc('\n',stderr);
X show_contour();
X c_token++;
X }
X else if (almost_equals(c_token,"d$ata")) {
X c_token++;
X if (!almost_equals(c_token,"s$tyle"))
X int_error("expecting keyword 'style'",c_token);
X (void) putc('\n',stderr);
X show_style("data",data_style);
X c_token++;
X }
X else if (almost_equals(c_token,"d$ummy")) {
X (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
X dummy_var[0], dummy_var[1]);
X c_token++;
X }
X else if (almost_equals(c_token,"fo$rmat")) {
X show_format();
X c_token++;
X }
X else if (almost_equals(c_token,"f$unctions")) {
X c_token++;
X if (almost_equals(c_token,"s$tyle")) {
X (void) putc('\n',stderr);
X show_style("functions",func_style);
X c_token++;
X }
X else
X show_functions();
X }
X else if (almost_equals(c_token,"lo$gscale")) {
X (void) putc('\n',stderr);
X show_logscale();
X c_token++;
X }
X else if (almost_equals(c_token,"of$fsets")) {
X (void) putc('\n',stderr);
X show_offsets();
X c_token++;
X }
X else if (almost_equals(c_token,"o$utput")) {
X (void) putc('\n',stderr);
X show_output();
X c_token++;
X }
X else if (almost_equals(c_token,"tit$le")) {
X (void) putc('\n',stderr);
X show_title();
X c_token++;
X }
X else if (almost_equals(c_token,"xl$abel")) {
X (void) putc('\n',stderr);
X show_xlabel();
X c_token++;
X }
X else if (almost_equals(c_token,"yl$abel")) {
X (void) putc('\n',stderr);
X show_ylabel();
X c_token++;
X }
X else if (almost_equals(c_token,"zl$abel")) {
X (void) putc('\n',stderr);
X show_zlabel();
X c_token++;
X }
X else if (almost_equals(c_token,"xzero$axis")) {
X (void) putc('\n',stderr);
X show_xzeroaxis();
X c_token++;
X }
X else if (almost_equals(c_token,"yzero$axis")) {
X (void) putc('\n',stderr);
X show_yzeroaxis();
X c_token++;
X }
X else if (almost_equals(c_token,"zeroa$xis")) {
X (void) putc('\n',stderr);
X show_xzeroaxis();
X show_yzeroaxis();
X c_token++;
X }
X else if (almost_equals(c_token,"la$bel")) {
X struct value a;
X int tag = 0;
X
X c_token++;
X if (!END_OF_COMMAND) {
X tag = (int)real(const_express(&a));
X if (tag <= 0)
X int_error("tag must be > zero", c_token);
X }
X
X (void) putc('\n',stderr);
X show_label(tag);
X }
X else if (almost_equals(c_token,"g$rid")) {
X (void) putc('\n',stderr);
X show_grid();
X c_token++;
X }
X else if (almost_equals(c_token,"k$ey")) {
X (void) putc('\n',stderr);
X show_key();
X c_token++;
X }
X else
X return (FALSE);
X return TRUE;
}
X
/* return TRUE if a command match, FALSE if not */
static BOOLEAN
show_two()
{
X if (almost_equals(c_token,"p$lot")) {
X (void) putc('\n',stderr);
X show_plot();
X c_token++;
X }
X else if (almost_equals(c_token,"par$ametric")) {
X (void) putc('\n',stderr);
X show_parametric();
X c_token++;
X }
X else if (almost_equals(c_token,"pol$ar")) {
X (void) putc('\n',stderr);
X show_polar();
X c_token++;
X }
X else if (almost_equals(c_token,"an$gles")) {
X (void) putc('\n',stderr);
X show_angles();
X c_token++;
X }
X else if (almost_equals(c_token,"ti$cs")) {
X (void) putc('\n',stderr);
X show_tics(TRUE,TRUE,TRUE);
X c_token++;
X }
X else if (almost_equals(c_token,"tim$e")) {
X (void) putc('\n',stderr);
X show_time();
X c_token++;
X }
X else if (almost_equals(c_token,"su$rface")) {
X (void) putc('\n',stderr);
X show_surface();
X c_token++;
X }
X else if (almost_equals(c_token,"xti$cs")) {
X show_tics(TRUE,FALSE,FALSE);
X c_token++;
X }
X else if (almost_equals(c_token,"yti$cs")) {
X show_tics(FALSE,TRUE,FALSE);
X c_token++;
X }
X else if (almost_equals(c_token,"zti$cs")) {
X show_tics(FALSE,FALSE,TRUE);
X c_token++;
X }
X else if (almost_equals(c_token,"sa$mples")) {
X (void) putc('\n',stderr);
X show_samples();
X c_token++;
X }
X else if (almost_equals(c_token,"isosa$mples")) {
X (void) putc('\n',stderr);
X show_isosamples();
X c_token++;
X }
X else if (almost_equals(c_token,"si$ze")) {
X (void) putc('\n',stderr);
X show_size();
X c_token++;
X }
X else if (almost_equals(c_token,"t$erminal")) {
X (void) putc('\n',stderr);
X show_term();
X c_token++;
X }
X else if (almost_equals(c_token,"rr$ange")) {
X (void) putc('\n',stderr);
X show_range('r',rmin,rmax);
X c_token++;
X }
X else if (almost_equals(c_token,"tr$ange")) {
X (void) putc('\n',stderr);
X show_range('t',tmin,tmax);
X c_token++;
X }
X else if (almost_equals(c_token,"ur$ange")) {
X (void) putc('\n',stderr);
X show_range('u',umin,umax);
X c_token++;
X }
X else if (almost_equals(c_token,"vi$ew")) {
X (void) putc('\n',stderr);
X show_view();
X c_token++;
X }
X else if (almost_equals(c_token,"vr$ange")) {
X (void) putc('\n',stderr);
X show_range('v',vmin,vmax);
X c_token++;
X }
X else if (almost_equals(c_token,"v$ariables")) {
X show_variables();
X c_token++;
X }
X else if (almost_equals(c_token,"ve$rsion")) {
X show_version();
X c_token++;
X }
X else if (almost_equals(c_token,"xr$ange")) {
X (void) putc('\n',stderr);
X show_range('x',xmin,xmax);
X c_token++;
X }
X else if (almost_equals(c_token,"yr$ange")) {
X (void) putc('\n',stderr);
X show_range('y',ymin,ymax);
X c_token++;
X }
X else if (almost_equals(c_token,"zr$ange")) {
X (void) putc('\n',stderr);
X show_range('z',zmin,zmax);
X c_token++;
X }
X else if (almost_equals(c_token,"z$ero")) {
X (void) putc('\n',stderr);
X show_zero();
X c_token++;
X }
X else if (almost_equals(c_token,"a$ll")) {
X c_token++;
X show_version();
X show_autoscale();
X show_border();
X show_clip();
X show_contour();
X show_mapping();
X (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
X dummy_var[0], dummy_var[1]);
X show_format();
X show_style("data",data_style);
X show_style("functions",func_style);
X show_grid();
X show_label(0);
X show_arrow(0);
X show_key();
X show_logscale();
X show_offsets();
X show_output();
X show_parametric();
X show_polar();
X show_angles();
X show_samples();
X show_isosamples();
X show_view();
X show_surface();
X show_size();
X show_term();
X show_tics(TRUE,TRUE,TRUE);
X show_time();
X if (parametric)
X if (!is_3d_plot)
X show_range('t',tmin,tmax);
X else {
X show_range('u',umin,umax);
X show_range('v',vmin,vmax);
X }
X if (polar)
X show_range('r',rmin,rmax);
X show_range('x',xmin,xmax);
X show_range('y',ymin,ymax);
X show_range('z',zmin,zmax);
X show_title();
X show_xlabel();
X show_ylabel();
X show_zlabel();
X show_zero();
X show_plot();
X show_variables();
X show_functions();
X c_token++;
X }
X else
X return (FALSE);
X return (TRUE);
}
X
X
/*********** support functions for 'show' **********/
static void
show_style(name,style)
char name[];
enum PLOT_STYLE style;
{
X fprintf(stderr,"\t%s are plotted with ",name);
X switch (style) {
X case LINES: fprintf(stderr,"lines\n"); break;
X case POINTS: fprintf(stderr,"points\n"); break;
X case IMPULSES: fprintf(stderr,"impulses\n"); break;
X case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
X case DOTS: fprintf(stderr,"dots\n"); break;
X case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
X }
}
X
static void
show_range(name,min,max)
char name;
double min,max;
{
X fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
}
X
static void
show_zero()
{
X fprintf(stderr,"\tzero is %g\n",zero);
}
X
static void
show_offsets()
{
X fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
}
X
static void
show_border()
{
X fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
}
X
static void
show_output()
{
X fprintf(stderr,"\toutput is sent to %s\n",outstr);
}
X
static void
show_samples()
{
X fprintf(stderr,"\tsampling rate is %d\n",samples);
}
X
static void
show_isosamples()
{
X fprintf(stderr,"\tiso sampling rate is %d\n",iso_samples);
}
X
static void
show_surface()
{
X fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
}
X
static void
show_view()
{
X fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
X surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
}
X
static void
show_size()
{
X fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
}
X
static void
show_title()
{
X fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
X title,title_xoffset,title_yoffset);
}
X
static void
show_xlabel()
{
X fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
X xlabel,xlabel_xoffset,xlabel_yoffset);
}
X
static void
show_ylabel()
{
X fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
X ylabel,ylabel_xoffset,ylabel_yoffset);
}
static void
show_zlabel()
{
X fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
X zlabel,zlabel_xoffset,zlabel_yoffset);
}
X
static void
show_xzeroaxis()
{
X fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
}
X
static void
show_yzeroaxis()
{
X fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
}
X
static void
show_label(tag)
X int tag; /* 0 means show all */
{
X struct text_label *this_label;
X BOOLEAN showed = FALSE;
X
X for (this_label = first_label; this_label != NULL;
X this_label = this_label->next) {
X if (tag == 0 || tag == this_label->tag) {
X showed = TRUE;
X fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
X this_label->tag, this_label->text,
X this_label->x, this_label->y, this_label->z);
X switch(this_label->pos) {
X case LEFT : {
X fprintf(stderr,"left");
X break;
X }
X case CENTRE : {
X fprintf(stderr,"centre");
X break;
X }
X case RIGHT : {
X fprintf(stderr,"right");
X break;
X }
X }
X fputc('\n',stderr);
X }
X }
X if (tag > 0 && !showed)
X int_error("label not found", c_token);
}
X
static void
show_arrow(tag)
X int tag; /* 0 means show all */
{
X struct arrow_def *this_arrow;
X BOOLEAN showed = FALSE;
X
X for (this_arrow = first_arrow; this_arrow != NULL;
X this_arrow = this_arrow->next) {
X if (tag == 0 || tag == this_arrow->tag) {
X showed = TRUE;
X fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
X this_arrow->tag,
X this_arrow->sx, this_arrow->sy, this_arrow->sz,
X this_arrow->ex, this_arrow->ey, this_arrow->ez,
X this_arrow->head ? "" : " (nohead)");
X }
X }
X if (tag > 0 && !showed)
X int_error("arrow not found", c_token);
}
X
static void
show_grid()
{
X fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
}
X
static void
show_key()
{
X switch (key) {
X case -1 :
X fprintf(stderr,"\tkey is ON\n");
X break;
X case 0 :
X fprintf(stderr,"\tkey is OFF\n");
X break;
X case 1 :
X fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
X break;
X }
}
X
static void
show_parametric()
{
X fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
}
X
static void
show_polar()
{
X fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
}
X
static void
show_angles()
{
X fprintf(stderr,"\tAngles are in ");
X switch (angles_format) {
X case ANGLES_RADIANS:
X fprintf(stderr, "radians\n");
X break;
X case ANGLES_DEGREES:
X fprintf(stderr, "degrees\n");
X break;
X }
}
X
X
static void
show_tics(showx, showy, showz)
X BOOLEAN showx, showy, showz;
{
X fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
X fprintf(stderr,"\tticslevel is %g\n",ticslevel);
X
X if (showx)
X show_ticdef(xtics, 'x', &xticdef);
X if (showy)
X show_ticdef(ytics, 'y', &yticdef);
X if (showz)
X show_ticdef(ztics, 'z', &zticdef);
X screen_ok = FALSE;
}
X
/* called by show_tics */
static void
show_ticdef(tics, axis, tdef)
X BOOLEAN tics; /* xtics ytics or ztics */
X char axis; /* 'x' 'y' or 'z' */
X struct ticdef *tdef; /* xticdef yticdef or zticdef */
{
X register struct ticmark *t;
X
X fprintf(stderr, "\t%c-axis tic labelling is ", axis);
X if (!tics) {
X fprintf(stderr, "OFF\n");
X return;
X }
X
X switch(tdef->type) {
X case TIC_COMPUTED: {
X fprintf(stderr, "computed automatically\n");
X break;
X }
X case TIC_SERIES: {
X if (tdef->def.series.end == VERYLARGE)
X fprintf(stderr, "series from %g by %g\n",
X tdef->def.series.start, tdef->def.series.incr);
X else
X fprintf(stderr, "series from %g by %g until %g\n",
X tdef->def.series.start, tdef->def.series.incr,
X tdef->def.series.end);
X break;
X }
X case TIC_USER: {
X fprintf(stderr, "list (");
X for (t = tdef->def.user; t != NULL; t=t->next) {
X if (t->label)
X fprintf(stderr, "\"%s\" ", t->label);
X if (t->next)
X fprintf(stderr, "%g, ", t->position);
X else
X fprintf(stderr, "%g", t->position);
X }
X fprintf(stderr, ")\n");
X break;
X }
X default: {
X int_error("unknown ticdef type in show_ticdef()", NO_CARET);
X /* NOTREACHED */
X }
X }
}
X
static void
show_time()
{
X fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
X (timedate)? "ON" : "OFF",
X time_xoffset,time_yoffset);
}
X
static void
show_term()
{
X char *str;
X
X fprintf(stderr,"\tterminal type is %s %s\n",
X term_tbl[term].name, term_options);
}
X
static void
show_plot()
{
X fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
}
X
static void
show_autoscale()
{
X fprintf(stderr,"\tautoscaling is ");
X if (parametric)
X if (is_3d_plot)
X fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
X else
X fprintf(stderr,"\tu: %s, v: %s, ",
X (autoscale_u)? "ON" : "OFF",
X (autoscale_v)? "ON" : "OFF");
X else fprintf(stderr,"\t");
X
X if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
X fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
X fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
X fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
}
X
static void
show_clip()
{
X fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
X
X if (clip_lines1)
X fprintf(stderr,
X "\tdrawing and clipping lines between inrange and outrange points\n");
X else
X fprintf(stderr,
X "\tnot drawing lines between inrange and outrange points\n");
X
X if (clip_lines2)
X fprintf(stderr,
X "\tdrawing and clipping lines between two outrange points\n");
X else
X fprintf(stderr,
X "\tnot drawing lines between two outrange points\n");
}
X
static void
show_mapping()
{
X fprintf(stderr,"\tmapping for 3-d data is ");
X
X switch (mapping3d) {
X case MAP3D_CARTESIAN:
X fprintf(stderr,"cartesian\n");
X break;
X case MAP3D_SPHERICAL:
X fprintf(stderr,"spherical\n");
X break;
X case MAP3D_CYLINDRICAL:
X fprintf(stderr,"cylindrical\n");
X break;
X }
}
X
static void
show_contour()
{
X fprintf(stderr,"\tcontour for surfaces are %s",
X (draw_contour)? "drawn" : "not drawn\n");
X
X if (draw_contour) {
X fprintf(stderr, " in %d levels on ", contour_levels);
X switch (draw_contour) {
X case CONTOUR_BASE:
X fprintf(stderr,"grid base\n");
X break;
X case CONTOUR_SRF:
X fprintf(stderr,"surface\n");
X break;
X case CONTOUR_BOTH:
X fprintf(stderr,"grid base and surface\n");
X break;
X }
X switch (contour_kind) {
X case CONTOUR_KIND_LINEAR:
X fprintf(stderr,"\t\tas linear segments\n");
X break;
X case CONTOUR_KIND_CUBIC_SPL:
X fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
X contour_pts);
X break;
X case CONTOUR_KIND_BSPLINE:
X fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
X contour_order, contour_pts);
X break;
X }
X }
}
X
static void
show_format()
{
X fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
X xformat, yformat, zformat);
}
X
static void
show_logscale()
{
X char *p;
X
X if (log_x && log_y && log_z)
X fprintf(stderr,"\tlogscaling all x, y and z axes\n");
X else {
X p = (log_x && log_y) /* Look for pairs. */
X ? "x and y"
X : (log_x && log_z)
X ? "x and z"
X : (log_y && log_z)
X ? "y and z"
X : NULL;
X if (p != NULL)
X fprintf(stderr,"\tlogscaling both %s axes\n",p);
X else {
X if (log_x)
X fprintf(stderr,"\tlogscaling x axis\n");
X if (log_y)
X fprintf(stderr,"\tlogscaling y axis\n");
X if (log_z)
X fprintf(stderr,"\tlogscaling z axis\n");
X if (!(log_x || log_y || log_z))
X fprintf(stderr,"\tno logscaling\n");
X }
X }
}
X
static void
show_variables()
{
register struct udvt_entry *udv = first_udv;
int len;
X
X fprintf(stderr,"\n\tVariables:\n");
X while (udv) {
X len = instring(udv->udv_name, ' ');
X fprintf(stderr,"\t%-*s ",len,udv->udv_name);
X if (udv->udv_undef)
X fputs("is undefined\n",stderr);
X else {
X fputs("= ",stderr);
X disp_value(stderr,&(udv->udv_value));
X (void) putc('\n',stderr);
X }
X udv = udv->next_udv;
X }
}
X
void /* used by plot.c */
show_version()
{
extern char version[];
extern char patchlevel[];
extern char date[];
extern char bug_email[];
static char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
int x;
long time();
X
X x = time((long *)NULL) & 1;
X fprintf(stderr,"\n\t%s\n\t%sversion %s\n",
X PROGRAM, OS, version);
X fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
X fprintf(stderr, "\tlast modified %s\n", date);
X fprintf(stderr,"\tCopyright (C) 1986, 1987, 1990, 1991 %s, %s\n",
X authors[x],authors[1-x]);
X fprintf(stderr, "\n\tSend bugs and comments to %s\n", bug_email);
}
X
X
X
X
X
X
X
X
SHAR_EOF
echo 'File gnuplot/setshow.c is complete' &&
chmod 0644 gnuplot/setshow.c ||
echo 'restore of gnuplot/setshow.c failed'
Wc_c="`wc -c < 'gnuplot/setshow.c'`"
test 63352 -eq "$Wc_c" ||
echo 'gnuplot/setshow.c: original size 63352, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= gnuplot/README ==============
if test -f 'gnuplot/README' -a X"$1" != X"-c"; then
echo 'x - skipping gnuplot/README (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting gnuplot/README (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/README' &&
X
X Where to get updates to GNUPLOT
X
Congratulations on getting this version of GNUPLOT! Unfortunately, it
may not be the most recent version ("you never know where this version
has been!"). You can be sure that it IS the most recent version by
checking one of the official distribution sites, guaranteed to be kept
up to date (of course, if you got this file from one of those sites,
you don't need to check!).
X
To hear automatically about future releases (and other GNUPLOT news),
join the mailing list; see below.
X
At the time of this writing, the following are the official
distribution sites and transfer instructions. Note that
prep.ai.mit.edu is NOT an official site, and may not be up to date.
Also, comp.sources.misc is usually a month or so behind us.
X
Date: Wed Sep 18 20:45:52 EDT 1991
Version: 3.0
X
In general, GNUPLOT 3.0 is available as the file gnuplot3.0.tar.Z.
There are no patches that bring GNUPLOT 2.02 up to 3.0, so you must
obtain the whole new release. Please obtain gnuplot from the site
nearest you.
X
USENET users:
X
X GNUPLOT 3.0 was posted to comp.sources.misc.
X
X
NORTH AMERICA:
X
X Anonymous ftp to dartmouth.edu (129.170.16.4)
X Fetch
X pub/gnuplot/gnuplot3.0.tar.Z
X in binary mode.
X
X Users without ftp capability can obtain it through a mail ftp
X server. Send a mail message saying 'help' to
X BITFTP@pucc.princeton.edu for instructions. For a uuencoded
X copy of the gnuplot sources (compressed tar file), send this
X message to BITFTP@pucc.princeton.edu:
X FTP DARTMOUTH.EDU UUENCODE
X USER ANONYMOUS
X CD pub/gnuplot
X BINARY
X GET gnuplot3.0.tar.Z
X QUIT
X
X
AUSTRALIA:
X
X Anonymous ftp to monu1.cc.monash.edu.au (130.194.1.101).
X Fetch pub/gnuplot3.0.tar.Z in binary mode.
X
X
EUROPE:
X
X Anonymous ftp to irisa.irisa.fr (131.254.2.3).
X Fetch pub/gnuplot3.0.tar.Z in binary mode.
X
----
X
X DISCLAIMER - This product is not related in any way to
X Pixar or any other commercial venture.
X
----
X CONTACTS:
X Please send any questions or comments to
X pixar!info-gnuplot@ucbvax.berkeley.edu.
X To join the above mailing list (or get yourself off), mail to
X pixar!info-gnuplot-request@ucbvax.berkeley.edu.
X Send bug reports and problems to
X pixar!bug-gnuplot@ucbvax.berkeley.edu.
X
X -Thomas Williams-
SHAR_EOF
chmod 0644 gnuplot/README ||
echo 'restore of gnuplot/README failed'
Wc_c="`wc -c < 'gnuplot/README'`"
test 2406 -eq "$Wc_c" ||
echo 'gnuplot/README: original size 2406, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= gnuplot/help.c ==============
if test -f 'gnuplot/help.c' -a X"$1" != X"-c"; then
echo 'x - skipping gnuplot/help.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting gnuplot/help.c (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/help.c' &&
/* GNUPLOT - help.c */
/*
X * Copyright (C) 1986, 1987, 1990, 1991 Thomas Williams, Colin Kelley
X *
X * Permission to use, copy, and distribute this software and its
X * documentation for any purpose with or without fee is hereby granted,
X * provided that the above copyright notice appear in all copies and
X * that both that copyright notice and this permission notice appear
X * in supporting documentation.
X *
X * Permission to modify the software is granted, but not the right to
X * distribute the modified code. Modifications are to be distributed
X * as patches to released version.
X *
X * This software is provided "as is" without express or implied warranty.
X *
X *
X * AUTHORS
X *
X * Original Software:
X * Thomas Williams, Colin Kelley.
X *
X * Gnuplot 2.0 additions:
X * Russell Lang, Dave Kotz, John Campbell.
X *
X * Gnuplot 3.0 additions:
X * Gershon Elber and many others.
X *
X * Send your comments or suggestions to
X * pixar!info-gnuplot@sun.com.
X * This is a mailing list; to join it send a note to
X * pixar!info-gnuplot-request@sun.com.
X * Send bug reports to
X * pixar!bug-gnuplot@sun.com.
X */
X
#include <stdio.h>
X
extern int errno;
X
extern int strcmp();
extern int strlen();
extern char *strcpy();
extern char *strncpy();
extern char *strcat();
extern char *strncat();
extern char *getenv();
extern FILE *fopen();
extern char *malloc();
X
extern int instring();
X
#define SAME 0 /* for strcmp() */
X
#include "help.h" /* values passed back */
X
/* help -- help subsystem that understands defined keywords
**
** Looks for the desired keyword in the help file at runtime, so you
** can give extra help or supply local customizations by merely editing
** the help file.
**
** The original (single-file) idea and algorithm is by John D. Johnson,
** Hewlett-Packard Company. Thanx and a tip of the Hatlo hat!
**
** Much extension by David Kotz for use in gnutex, and then in gnuplot.
** Added output paging support, both unix and builtin. Rewrote completely
** to read helpfile into memory, avoiding reread of help file. 12/89.
**
** Modified by Russell Lang to avoid reading completely into memory
** if MSDOS defined. This uses much less memory. 6/91
**
** The help file looks like this (the question marks are really in column 1):
**
** ?topic
** This line is printed when the user wants help on "topic".
** ?keyword
** ?Keyword
** ?KEYWORD
** These lines will be printed on the screen if the user wanted
** help on "keyword", "Keyword", or "KEYWORD". No casefolding is
** done on the keywords.
** ?subject
** ?alias
** This line is printed for help on "subject" and "alias".
** ?
** ??
** Since there is a null keyword for this line, this section
** is printed when the user wants general help (when a help
** keyword isn't given). A command summary is usually here.
** Notice that the null keyword is equivalent to a "?" keyword
** here, because of the '?' and '??' topic lines above.
** If multiple keywords are given, the first is considered the
** 'primary' keyword. This affects a listing of available topics.
** ?last-subject
** Note that help sections are terminated by the start of the next
** '?' entry or by EOF. So you can't have a leading '?' on a line
** of any help section. You can re-define the magic character to
** recognize in column 1, though, if '?' is too useful. (Try ^A.)
*/
X
#define KEYFLAG '?' /* leading char in help file topic lines */
X
/*
** Calling sequence:
** int result; # 0 == success
** char *keyword; # topic to give help on
** char *pathname; # path of help file
** int subtopics; # set to TRUE if only subtopics to be listed
** # returns TRUE if subtopics were found
** result = help(keyword, pathname, &subtopics);
** Sample:
** cmd = "search\n";
** helpfile = "/usr/local/lib/program/program.help";
** subtopics = FALSE;
** if (help(cmd, helpfile, &subtopics) != H_FOUND)
** printf("Sorry, no help for %s", cmd);
**
**
** Speed this up by replacing the stdio calls with open/close/read/write.
*/
#ifdef WDLEN
# define PATHSIZE WDLEN
#else
# define PATHSIZE BUFSIZ
#endif
X
typedef int boolean;
#ifndef TRUE
#define TRUE (1)
#define FALSE (0)
#endif
X
typedef struct line_s LINEBUF;
struct line_s {
X char *line; /* the text of this line */
X LINEBUF *next; /* the next line */
};
X
typedef struct linkey_s LINKEY;
struct linkey_s {
X char *key; /* the name of this key */
X long pos; /* ftell position */
X LINEBUF *text; /* the text for this key */
X boolean primary; /* TRUE -> is a primary name for a text block */
X LINKEY *next; /* the next key in linked list */
};
X
typedef struct key_s KEY;
struct key_s {
X char *key; /* the name of this key */
X long pos; /* ftell position */
X LINEBUF *text; /* the text for this key */
X boolean primary; /* TRUE -> is a primary name for a text block */
};
static LINKEY *keylist = NULL; /* linked list of keys */
static KEY *keys = NULL; /* array of keys */
static int keycount = 0; /* number of keys */
static FILE *helpfp = NULL;
X
static int LoadHelp();
static void sortkeys();
static int keycomp();
static LINEBUF *storeline();
static LINKEY *storekey();
static KEY *FindHelp();
static boolean Ambiguous();
X
/* Help output */
static void PrintHelp();
static void ShowSubtopics();
static void StartOutput();
static void OutLine();
static void EndOutput();
static FILE *outfile; /* for unix pager, if any */
static int pagelines; /* count for builtin pager */
#define SCREENSIZE 24 /* lines on screen (most have at least 24) */
X
/* help:
X * print a help message
X * also print available subtopics, if subtopics is TRUE
X */
help(keyword, path, subtopics)
X char *keyword; /* on this topic */
X char *path; /* from this file */
X boolean *subtopics; /* (in) - subtopics only? */
X /* (out) - are there subtopics? */
{
X static char oldpath[PATHSIZE] = ""; /* previous help file */
X int status; /* result of LoadHelp */
X KEY *key; /* key that matches keyword */
X
X /*
X ** Load the help file if necessary (say, first time we enter this routine,
X ** or if the help file changes from the last time we were called).
X ** Also may occur if in-memory copy was freed.
X ** Calling routine may access errno to determine cause of H_ERROR.
X */
X errno = 0;
X if (strncmp(oldpath, path, PATHSIZE) != SAME)
X FreeHelp();
X if (keys == NULL) {
X status = LoadHelp(path);
X if (status == H_ERROR)
X return(status);
X
X /* save the new path in oldpath */
X if (strlen(path) < PATHSIZE)
X (void) strcpy(oldpath, path);
X else { /* not enough room in oldpath, sigh */
X (void) strncpy(oldpath, path, PATHSIZE - 1);
X oldpath[PATHSIZE - 1] = '\0';
X }
X }
X
X /* look for the keyword in the help file */
X key = FindHelp(keyword);
X if (key != NULL) {
X /* found the keyword: print help and return */
X PrintHelp(key, subtopics);
X status = H_FOUND;
X } else {
X status = H_NOTFOUND;
X }
X
X return(status);
}
X
/* we only read the file once, into memory
X * except for MSDOS when we don't read all the file -
X * just the keys and location of the text
X */
static int
LoadHelp(path)
X char *path;
{
X LINKEY *key; /* this key */
X long pos; /* ftell location within help file */
X char buf[BUFSIZ]; /* line from help file */
X LINEBUF *head; /* head of text list */
X LINEBUF *firsthead = NULL;
X boolean primary; /* first ? line of a set is primary */
X boolean flag;
X
X if ((helpfp = fopen(path, "r")) == NULL) {
X /* can't open help file, so error exit */
X return (H_ERROR);
X }
X
X /*
X ** The help file is open. Look in there for the keyword.
X */
X (void) fgets(buf, BUFSIZ - 1, helpfp);
X while (!feof(helpfp)) {
X /*
X ** Make an entry for each synonym keyword
X */
X primary = TRUE;
X while (buf[0] == KEYFLAG) {
X key = storekey(buf+1); /* store this key */
X key->primary = primary;
X key->text = NULL; /* fill in with real value later */
X key->pos = 0; /* fill in with real value later */
X primary = FALSE;
X pos = ftell(helpfp);
X if (fgets(buf, BUFSIZ - 1, helpfp) == (char *)NULL)
X break;
X }
X /*
X ** Now store the text for this entry.
X ** buf already contains the first line of text.
X */
#ifndef MSDOS
X firsthead = storeline(buf);
X head = firsthead;
#endif
X while ( (fgets(buf, BUFSIZ - 1, helpfp) != (char *)NULL)
X && (buf[0] != KEYFLAG) ){
#ifndef MSDOS
X /* save text line */
X head->next = storeline(buf);
X head = head->next;
#endif
X }
X /* make each synonym key point to the same text */
X do {
X key->pos = pos;
X key->text = firsthead;
X flag = key->primary;
X key = key->next;
X } while ( flag!=TRUE && key!=NULL );
X }
#ifndef MSDOS
X (void) fclose(helpfp);
#endif
X
X /* we sort the keys so we can use binary search later */
X sortkeys();
X return(H_FOUND); /* ok */
}
X
/* make a new line buffer and save this string there */
static LINEBUF *
storeline(text)
X char *text;
{
X LINEBUF *new;
X
X new = (LINEBUF *)malloc(sizeof(LINEBUF));
X if (new == NULL)
X int_error("not enough memory to store help file", -1);
X if (text != NULL) {
X new->line = (char *) malloc((unsigned int)(strlen(text)+1));
X if (new->line == NULL)
X int_error("not enough memory to store help file", -1);
X (void) strcpy(new->line, text);
X } else
X new->line = NULL;
X
X new->next = NULL;
X
X return(new);
}
X
/* Add this keyword to the keys list, with the given text */
static LINKEY *
storekey(key)
X char *key;
{
X LINKEY *new;
X
X key[strlen(key)-1] = '\0'; /* cut off \n */
X
X new = (LINKEY *)malloc(sizeof(LINKEY));
X if (new == NULL)
X int_error("not enough memory to store help file", -1);
X new->key = (char *) malloc((unsigned int)(strlen(key)+1));
X if (new->key == NULL)
X int_error("not enough memory to store help file", -1);
X (void) strcpy(new->key, key);
X
X /* add to front of list */
X new->next = keylist;
X keylist = new;
X keycount++;
X return(new);
}
X
/* we sort the keys so we can use binary search later */
/* We have a linked list of keys and the number.
X * to sort them we need an array, so we reform them into an array,
X * and then throw away the list.
X */
static void
sortkeys()
{
X LINKEY *p,*n; /* pointers to linked list */
X int i; /* index into key array */
X
X /* allocate the array */
X keys = (KEY *)malloc((unsigned int)((keycount+1) * sizeof(KEY)));
X if (keys == NULL)
X int_error("not enough memory to store help file", -1);
X
X /* copy info from list to array, freeing list */
X for (p = keylist, i = 0; p != NULL; p = n, i++) {
X keys[i].key = p->key;
X keys[i].pos = p->pos;
X keys[i].text = p->text;
X keys[i].primary = p->primary;
X n = p->next;
X free( (char *)p );
X }
X
X /* a null entry to terminate subtopic searches */
X keys[keycount].key = NULL;
X keys[keycount].pos = 0;
X keys[keycount].text = NULL;
X
X /* sort the array */
X /* note that it only moves objects of size (two pointers + long + int) */
X /* it moves no strings */
X qsort((char *)keys, keycount, sizeof(KEY), keycomp);
}
X
static int
keycomp(a, b)
X KEY *a,*b;
{
X return (strcmp(a->key, b->key));
}
X
/* Free the help file from memory. */
/* May be called externally if space is needed */
void
FreeHelp()
{
X int i; /* index into keys[] */
X LINEBUF *t, *next;
X
X if (keys == NULL)
X return;
X
X for (i = 0; i < keycount; i++) {
X free( (char *)keys[i].key );
X if (keys[i].primary) /* only try to release text once! */
X for (t = keys[i].text; t != NULL; t = next) {
X free( (char *)t->line );
X next = t->next;
X free( (char *)t );
X }
X }
X free( (char *)keys );
X keys = NULL;
X keycount = 0;
#ifdef MSDOS
X (void) fclose(helpfp);
#endif
}
X
/* FindHelp:
X * Find the key that matches the keyword.
X * The keys[] array is sorted by key.
X * We could use a binary search, but a linear search will aid our
X * attempt to allow abbreviations. We search for the first thing that
X * matches all the text we're given. If not an exact match, then
X * it is an abbreviated match, and there must be no other abbreviated
X * matches -- for if there are, the abbreviation is ambiguous.
X * We print the ambiguous matches in that case, and return not found.
X */
static KEY * /* NULL if not found */
FindHelp(keyword)
X char *keyword; /* string we look for */
{
X KEY *key;
X int len = strlen(keyword);
X int compare;
X
X for (key = keys, compare = 1; key->key != NULL && compare > 0; key++) {
X compare = strncmp(keyword, key->key, len);
X if (compare == 0) /* we have a match! */
X if (!Ambiguous(key, len)) {
X /* non-ambiguous abbreviation */
X (void) strcpy(keyword, key->key); /* give back the full spelling */
X return(key); /* found!! */
X }
X }
X
X /* not found, or ambiguous */
X return(NULL);
}
X
/* Ambiguous:
X * Check the key for ambiguity up to the given length.
X * It is ambiguous if it is not a complete string and there are other
X * keys following it with the same leading substring.
X */
static boolean
Ambiguous(key, len)
X KEY *key;
X int len;
{
X char *first;
X char *prev;
X boolean status = FALSE; /* assume not ambiguous */
X int compare;
X int sublen;
X
X if (key->key[len] == '\0')
X return(FALSE);
X
X for (prev = first = key->key, compare = 0, key++;
X key->key != NULL && compare == 0; key++) {
X compare = strncmp(first, key->key, len);
X if (compare == 0) {
X /* So this key matches the first one, up to len.
X * But is it different enough from the previous one
X * to bother printing it as a separate choice?
X */
X sublen = instring(prev+len, ' ');
X if (strncmp(key->key, prev, len+sublen) != 0) {
X /* yup, this is different up to the next space */
X if (!status) {
X /* first one we have printed is special */
X fprintf(stderr,
X "Ambiguous request '%.*s'; possible matches:\n",
X len, first);
X fprintf(stderr, "\t%s\n", prev);
X status = TRUE;
X }
X fprintf(stderr, "\t%s\n", key->key);
X prev = key->key;
X }
X }
X }
X
X return(status);
}
X
/* PrintHelp:
X * print the text for key
X */
static void
PrintHelp(key, subtopics)
X KEY *key;
X boolean *subtopics; /* (in) - subtopics only? */
X /* (out) - are there subtopics? */
{
X LINEBUF *t;
#ifdef MSDOS
X char buf[BUFSIZ]; /* line from help file */
#endif
X
X StartOutput();
X
X if (subtopics == NULL || !*subtopics) {
#ifdef MSDOS
X fseek(helpfp,key->pos,0);
X while ( (fgets(buf, BUFSIZ - 1, helpfp) != (char *)NULL)
X && (buf[0] != KEYFLAG) ) {
X OutLine(buf);
X }
#else
X for (t = key->text; t != NULL; t = t->next)
X OutLine(t->line); /* print text line */
#endif
X }
X
X ShowSubtopics(key, subtopics);
X OutLine("\n");
X
X EndOutput();
}
X
/* ShowSubtopics:
X * Print a list of subtopic names
X */
#define PER_LINE 4
X
static void
ShowSubtopics(key, subtopics)
X KEY *key; /* the topic */
X boolean *subtopics; /* (out) are there any subtopics */
{
X int subt = 0; /* printed any subtopics yet? */
X KEY *subkey; /* subtopic key */
X int len; /* length of key name */
X char line[BUFSIZ]; /* subtopic output line */
X char *start; /* position of subname in key name */
X int sublen; /* length of subname */
X int pos;
X char *prev = NULL; /* the last thing we put on the list */
X
X *line = '\0';
X len = strlen(key->key);
X
X for (subkey = key+1; subkey->key != NULL; subkey++) {
X if (strncmp(subkey->key, key->key, len) == 0) {
X /* find this subtopic name */
X start = subkey->key + len;
X if (len > 0)
X if (*start == ' ')
X start++; /* skip space */
X else
X break; /* not the same topic after all */
X else /* here we are looking for main topics */
X if (!subkey->primary)
X continue; /* not a main topic */
X sublen = instring(start, ' ');
X if (prev == NULL || strncmp(start, prev, sublen) != 0) {
X if (subt == 0) {
X subt++;
X if (len)
X (void) sprintf(line, "\nSubtopics available for %s:\n",
X key->key);
X else
X (void) sprintf(line, "\nHelp topics available:\n");
X OutLine(line);
X *line = '\0';
X pos = 0;
X }
X if (pos == PER_LINE) {
X (void) strcat(line, "\n");
X OutLine(line);
X *line = '\0';
X pos = 0;
X }
X (void) strcat(line, "\t");
X (void) strncat(line, start, sublen);
X pos++;
X prev = start;
X }
X } else {
X /* new topic */
X break;
X }
X }
X
X /* put out the last line */
X if (subt > 0 && pos > 0) {
X (void) strcat(line, "\n");
X OutLine(line);
X }
X
/*
X if (subt == 0) {
X OutLine("\n");
X OutLine("No subtopics available\n");
X }
*/
X
X if (subtopics)
X *subtopics = (subt != 0);
}
X
X
/* StartOutput:
X * Open a file pointer to a pipe to user's $PAGER, if there is one,
X * otherwise use our own pager.
X */
static void
StartOutput()
{
#ifdef unix
X char *pager_name = getenv("PAGER");
X extern FILE *popen();
X
X if (pager_name != NULL && *pager_name != '\0')
X if ((outfile = popen(pager_name, "w")) != (FILE *)NULL)
X return; /* success */
X outfile = stderr;
X /* fall through to built-in pager */
#endif
X
X /* built-in pager */
X pagelines = 0;
}
X
/* write a line of help output */
/* line should contain only one \n, at the end */
static void
OutLine(line)
X char *line;
{
X int c; /* dummy input char */
#ifdef unix
X if (outfile != stderr) {
X fputs(line, outfile);
X return;
X }
#endif
X
X /* built-in dumb pager */
SHAR_EOF
true || echo 'restore of gnuplot/help.c failed'
fi
echo 'End of part 2'
echo 'File gnuplot/help.c is continued in part 3'
echo 3 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent@uunet.uu.net.