[alt.sources] Fchart part 04/04

fs@uwasa.fi (Filip Sawicki LAKE) (06/04/90)

Submitted-by: fs@chyde
Archive-name: Fchart/part04

#!/bin/sh
# This is part 04 of Fchart
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= fstyles.i ==============
echo "x - extracting fstyles.i (Text)"
sed 's/^X//' << 'SHAR_EOF' > fstyles.i &&
X/* Fchart -- fstyles.i
X *
X * Scratch file containing old version of styles implementation.
X * Unfortunately, I had neither time nor energy to finish writing
X * the second version of it. Maybe later.
X *
X * Modifying this file is not allowed or granted.
X *
X * Copyright (C) 1990 Piotr Filip Sawicki
X *
X * Don't modify this code: throw it away "as is" !
X *
X */
X
Xstruct sqrdim{
X	int numxsqrs;
X	int numysqrs;
X};
X
Xstruct sqrdim *dividesquares(xlen, ylen, numbox)
Xint xlen, ylen, numbox;
X/* find the best pie box layout for given screen. not optimal. sniff :-(
X   write better one, if you can and have any idea how to do that */
X{
X	long i, j;	/* sometimes go very high */
X	static struct sqrdim ST;
X
X	for (i=1; i<=numbox; i++)
X		for (j=numbox/i; j<=numbox; j++)
X			if (i*j>=numbox && 5*ylen/i*j>=xlen && 3*ylen/i*j/2<=xlen)
X				goto found;
X
X	int_error("Division not found. Please inform author: fs@uwasa.fi", NO_CARET);
X	
Xfound:
X	/* first check for boundary conditions */
X	if ((i-1)*j >= numbox)
X		i--;
X	else if ((j-1)*i >= numbox)
X		j--;
X	ST.numxsqrs = j;
X	ST.numysqrs = i;
X	return(&ST);
X}
X
Xdr_pies(xplot)
XBOOLEAN xplot; 
X/* draw piecharts */
X{
X	int x, y, i, j, k = 0, ax, ay, b_i, b_j, b_n;
X	int incr = (p_clockwise ? -1 : 1);
X	double all, st_an, angl, HLangle, vprev, lastang;
X	int box_x, box_y, base_rad, radius;
X	struct chunk *chn, *chnHL;
X	struct dfile *f;
X	vreal *HL_me = NULL, *bound;
X	int numHL = -1;
X	double radrad = (radexp>1.0 ? radexp/100.0 : radexp);
X	double trash = (treshold>1.0 ? treshold/100.0 : treshold);
X	BOOLEAN do_lab = data_head.labels;
X	double treshed = 0.0;	/* anything tresholded ? */
X	char nlab[250], *lblpt;
X	struct sqrdim CX, *divided = &CX;
X
X	if (xplot)
X		return(0);
X
X	box_x = xmaxp - xbase;
X	box_y = ymaxp - ybase;
X	if (data_head.chunks == 1) {
X		divided->numxsqrs = 1;
X		divided->numysqrs = 1;
X	}
X	else {
X		divided = dividesquares(box_x, box_y, data_head.chunks);
X		box_x /= divided->numxsqrs;
X		box_y /= divided->numysqrs;
X	}
X
X	if (box_x < box_y) base_rad = (int) (box_x/2*MARGIN);
X	else base_rad = (int) (box_y/2*MARGIN);
X	/* reserve space for labels - at least 5 chars */
X	if (box_y - base_rad*2 < t->v_char*3)
X		base_rad += box_y - base_rad*2 - t->v_char*3;	/* <0, so OK */
X	if (base_rad<=0)
X		return(0);
X	i = (data_head.chunks != 1);
X	if (box_x - base_rad*2 < t->h_char*(10+i*5))
X		base_rad += box_x - base_rad*2 - t->h_char*(10+i*5);	/* <0, so OK */
X
X	if (base_rad<=0)
X		return(0);
X
X	b_n = divided->numxsqrs * divided->numysqrs;
X	b_j = divided->numysqrs - 1;
X	b_i = 0;
X	(*t->linetype)(0);		/* one type. looks better for piecharts */
X
X	/* main loop with "double engine" */
X	for (f=data_head.dnxt; b_n--; (++b_i == divided->numxsqrs ? b_i=0, --b_j : 1)) {
X		if (b_n >= data_head.chunks)
X			continue;	/* leave topmost boxes empty */
X		
X		x = box_x/2 + xbase + b_i*box_x;
X		y = box_y/2 + ybase + b_j*box_y;
X		
X		chn = f->data;
X		i = j = 0;
X		all = vprev = 0.0;
X		while (chn) {
X			if (i==chn->used) {
X				chn = chn->next;
X				i = 0;
X				continue;
X			}
X			if (chn->dval[i] != VERYLARGE) {
X				all += chn->dval[i];
X				if (!HL_me && radrad) {
X					vprev += chn->dval[i];
X					if (f->makeHL == HL_MIN && chn->dval[i] == f->d_min ||
X						f->makeHL == HL_MAX && chn->dval[i] == f->d_max ||
X						f->makeHL == j ||
X						f->makeHL == HL_NON && 
X											(data_head.makeHL == HL_MIN && chn->dval[i] == data_head.d_min ||
X											 data_head.makeHL == HL_MAX && chn->dval[i] == data_head.d_max ||
X						 					 data_head.makeHL == j)) {
X						HL_me = chn->dval+i;
X						chnHL = chn;
X						numHL = i;
X						k = j;
X					}
X				}
X			}
X			i++;
X			j++;
X		}
X		if (f->points == 1) HL_me = NULL;
X		
X		if (HL_me) {
X			radius = (int) (base_rad/(1+radrad));
X		}
X		else 
X			radius = base_rad;
X		
X		if (HL_me) HLangle = *HL_me/all*Pi*2;
X		
X		if (!HL_me) {     
X			chn = f->data;
X			i   = 0;
X			st_an = 0.0;
X		}
X		else {
X			chn = chnHL;
X			i   = numHL;
X			if (explode == DEFAULT)
X				st_an = incr*vprev/all*Pi*2 - incr*HLangle;
X			else
X				st_an = (int)explode*Pi/2 - incr*HLangle/2;
X		}
X		
X		/* draw segments */
X		lastang = angl = st_an;
X		bound = chn->dval+i;
X		j = k;
X		do {
X			if (chn->dval[i] != VERYLARGE) {
X				if (!HL_me && ((chn->dval[i]/all) <= trash))
X					treshed += chn->dval[i];
X				else {
X					lastang = angl;
X					angl += incr*chn->dval[i]/all*Pi*2;
X					(*t->move)(MCx(x,radius,Pi/2+angl),MCy(y,radius,Pi/2+angl));
X					(*t->vector)(x,y);
X					if (j!=k || !HL_me) {		/* if explode, don't label the first drawn element */
X						ax = MCx(x+t->h_char*cos(Pi/2+(angl+lastang)/2), radius, Pi/2+(angl+lastang)/2);
X						ay = MCy(y+t->v_char*sin(Pi/2+(angl+lastang)/2), radius, Pi/2+(angl+lastang)/2);
X						if (chn->vlbl && chn->vlbl[i])
X							lblpt = chn->vlbl[i];
X						else if (do_lab)
X							lblpt = make_labl((double)j+first_element);
X						else
X							lblpt = "";
X						strcpy(nlab, lblpt);
X						if (*nlab) strcat(nlab,"-");
X						strcat(nlab, "(");
X						strcat(nlab, make_labl(chn->dval[i]));
X						strcat(nlab, ")");
X						put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
X					}
X				}
X			}
X			i++;
X			j++;
X			if (i==chn->used) {
X				i=0;
X				if (chn->next) chn=chn->next;
X				else chn = f->data, j = 0;				/* wrap around */
X			}
X		} while (&chn->dval[i] != bound);
X		
X		/* it's possible, that the first/last radius has not been drawn */
X		(*t->move)(x,y);
X		(*t->vector)(MCx(x,radius,Pi/2+st_an),MCy(y,radius,Pi/2+st_an));
X		
X		if (HL_me) {
X			lastang = Pi/2+st_an+incr*HLangle;
X			put_arc(x,y,radius,st_an+incr*HLangle+Pi/2,incr*(Pi*2-HLangle));
X			x += radrad*radius*cos(incr*HLangle/2+st_an+Pi/2);
X			y += radrad*radius*sin(incr*HLangle/2+st_an+Pi/2);
X			(*t->move)(MCx(x,radius,Pi/2+st_an),MCy(y,radius,Pi/2+st_an));
X			(*t->vector)(x,y);
X			(*t->vector)(MCx(x,radius,lastang),
X						 MCy(y,radius,lastang));
X			put_arc(x,y,radius,st_an+Pi/2,incr*HLangle);
X			lastang = Pi/2+st_an+incr*HLangle/2;
X			ax = MCx(x+t->h_char*cos(lastang), radius, lastang);
X			ay = MCy(y+t->v_char*sin(lastang), radius, lastang);
X			if (chn->vlbl && chn->vlbl[i])
X				lblpt = chn->vlbl[i];
X			else if (do_lab)
X				lblpt = make_labl((double)j+first_element);
X			else
X				lblpt = "";
X			strcpy(nlab, lblpt);
X			strcat(nlab, "-(");
X			strcat(nlab, make_labl(chn->dval[i]));
X			strcat(nlab, ")");
X			put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
X		}
X		else {
X			put_arc(x,y,radius,0.0,Pi*2);
X			if (treshed != 0) {
X				lastang = (st_an+angl)/2 - Pi/2;	/* remainder's mediana - but why minus ??? */
X				ax = MCx(x+t->h_char*cos(lastang), radius, lastang);
X				ay = MCy(y+t->v_char*sin(lastang), radius, lastang);
X				strcpy(nlab, thrname);
X				strcat(nlab, "-(");
X				strcat(nlab, make_labl(treshed));
X				strcat(nlab, ")");
X				put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
X			}
X		}
X		
X		f = f->dnxt;
X		
X	}  /* main loop */
X	
X	return(1);
X}
X
Xdr_abar(xplot)
XBOOLEAN xplot;
X/* draw adjacent barchart within given values and viewport */
X{
X	double unit, what;
X	double based = log_y ? log10(base) : base;
X	int bw, ib, sp, of, gw, tw, i, j, k, pos, ibase;
X	int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
X	int dirNS = !((int)gravity&1);
X	struct chunk *chn;
X	double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
X	double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
X	double d_sp = (b_spc>1.0 ? b_spc/100.0 : b_spc);
X	int incr = (b_clockwise ? 1 : -1), adit;
X	struct dfile *f = &data_head;
X	double minv, maxv, full;
X	int linetype, cx, cy;
X	int coff = 2*t->v_char/3;
X	char *barlab, bet[200];
X
X	if (f->chunks == 1)
X		xplot = FALSE;		/* sometimes important and faster */
X
X	minv = (data_head.d_min < based ? data_head.d_min : based);
X	maxv = (data_head.d_max > based ? data_head.d_max : based);
X	set_hm(minv, maxv);
X	
X    of = nint((xmaxp-xbase)*(1-MARGIN));
X	xbase += of; xmaxp -= of;
X	of = nint((ymaxp-ybase)*(1-MARGIN));
X	ybase += of; ymaxp -= of;
X
X	/* reserve space for labels */
X	i = xplot ? 2 : 3;
X	switch (gravity) {
X		case SOUTH: ybase += i*t->v_char, ymaxp -= t->v_char;
X			break;
X		case NORTH: ybase += t->v_char, ymaxp -= i*t->v_char;
X			break;
X		case EAST:  xbase += (howmuch+1)*t->h_char, xmaxp -= i*t->h_char;
X			break;
X		case WEST:  xbase += i*t->h_char, xmaxp -= (howmuch+1)*t->h_char;
X			break;
X	}
X
X	if (autoscale)
X		adit = 0;
X	else
X		adit = do_axis(&minv,&maxv,xbase,xmaxp,ybase,ymaxp,FALSE);
X	full = maxv-minv;
X
X	if (f->chunks == 1)
X		unit = f->points + (f->points-1)*d_ib;
X	else if (xplot)
X		unit = f->chunks*f->points + (f->chunks-1)*f->points*d_ib + (f->points-1)*d_sp;
X	else
X		unit = f->points*f->chunks + (f->points-1)*f->chunks*d_ib + (f->chunks-1)*d_sp;
X	if (!autoscale)
X		unit += d_ib;
X	
X	bw = ((dirNS ? xmaxp-xbase : ymaxp-ybase)-adit)/unit;
X	if ((double)bw/resolution > d_bw) {
X		bw = resolution*d_bw;
X		of = ((dirNS ? xmaxp-xbase : ymaxp-ybase) - adit - bw*unit)/2 + adit;
X	}
X	else of = adit;
X	if (!bw) return(0);
X
X	ib = nint(bw*d_ib);
X	if (f->chunks > 1) sp = nint(bw*d_sp);
X	else sp = ib;
X	gw = (xplot ? f->chunks : f->points)*(bw+ib)-ib;
X	tw = nint(bw*unit);
X	if (!autoscale)		/* make space between axis and bars */
X		of += ib;
X	resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
X	unit = resolution/full;
X
X	(*t->linetype)(-1);
X	switch (gravity) {
X		case NORTH:
X			(*t->move)(xbase,ibase=nint((maxv-based)*unit)+ybase);
X			(*t->vector)(xmaxp-adit,ibase);
X			break;
X		case SOUTH:
X			(*t->move)(xbase+adit,ibase=nint((based-minv)*unit)+ybase);
X			(*t->vector)(xmaxp,ibase);
X			break;
X		case WEST:
X			(*t->move)(ibase=nint((based-minv)*unit)+xbase,ybase);
X			(*t->vector)(ibase,ymaxp-adit);
X			break;
X		case EAST:
X			(*t->move)(ibase=nint((maxv-based)*unit)+xbase,ybase+adit);
X			(*t->vector)(ibase,ymaxp);
X			break;
X		default: break;
X	}
X
X	if (data_head.chunks > 1)
X		init_acrs();
X
X	(*t->linetype)(linetype=0);
X	for (k=0, f=f->dnxt; f; f=f->dnxt, k++) {
X		j = i = 0;
X		chn = f->data;
X		
X		if (b_clockwise) pos = of + k*(xplot ? bw+ib : gw+sp);
X		else pos = of + tw - k*(xplot ? bw+ib : gw+sp) - bw; 
X
X		if (xplot)
X			(*t->linetype)(k);
X		else 					/* print plot name */
X			switch (gravity) {
X				case SOUTH: put_lab(xbase+pos+gw/2, ybase-5*(int)t->v_char/2, f->fname, 0, gw);
X					break;
X				case NORTH: put_lab(xmaxp-pos-gw/2, ymaxp+5*(int)t->v_char/2, f->fname, 0, gw);
X					break;
X				case WEST:  put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-gw/2, f->fname, 1, gw);
X					break;
X				case EAST:  put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+gw/2, f->fname, 1, gw);
X					break;
X			}
X			
X		while (chn) {
X			if (i==chn->used) {
X				i = 0;
X				chn = chn->next;
X				continue;
X			}
X			if ((what = chn->dval[i]) != VERYLARGE) {
X				if (f->makeHL == HL_MIN && what == f->d_min ||
X					f->makeHL == HL_MAX && what == f->d_max ||
X					f->makeHL == j ||
X					data_head.makeHL == HL_MIN && what == data_head.d_min ||
X					data_head.makeHL == HL_MAX && what == data_head.d_max ||
X					data_head.makeHL == j)
X					(*t->linetype)(linetype=-1);
X				if (!xplot)
X					if (chn->vlbl && chn->vlbl[i])
X						barlab = chn->vlbl[i];
X					else if (data_head.labels && f->labels)
X						strcpy(barlab=bet, make_labl((double)j+first_element));
X					else
X						barlab = NULL;
X				else
X					barlab = NULL;
X				switch (gravity) {
X					case SOUTH: put_bar(xbase+pos,ibase, bw,cy=nint((what-based)*unit),0);
X						put_lab(xbase+pos+bw/2, ibase+(cy>0?cy:0)+coff, make_labl(what), 0, bw);
X						put_lab(xbase+pos+bw/2, ybase-3*(int)t->v_char/2, barlab, 0, bw);
X						break;
X					case NORTH: put_bar(xmaxp-pos,ibase,-bw,cy=nint((based-what)*unit),0);
X						put_lab(xmaxp-pos-bw/2, ibase+(cy<0?cy:0)-coff, make_labl(what), 0, bw);
X						put_lab(xmaxp-pos-bw/2, ymaxp+3*(int)t->v_char/2, barlab, 0, bw);
X						break;
X					case WEST:  put_bar(ibase,ymaxp-pos-bw,cx=nint((what-based)*unit), bw,1);
X						put_txt(ibase+(cx>0?cx:0)+(int)t->h_char, ymaxp-pos-bw/2, make_labl(what), LEFT, 0);
X						put_lab(xbase-3*(int)t->h_char/2, ymaxp-pos-bw/2, barlab, 1, bw);
X						break;
X					case EAST:  put_bar(ibase,ybase+pos+bw,cx=nint((based-what)*unit),-bw,1);
X						put_txt(ibase+(cx<0?cx:0)-(int)t->h_char, ybase+pos+bw/2, make_labl(what), RIGHT, 0);
X						put_lab(xmaxp+3*(int)t->h_char/2, ybase+pos+bw/2, barlab, 1, bw);
X						break;
X				}
X				if (linetype != 0) (*t->linetype)(linetype=0);
X			}
X			if (!k && xplot) {	/* make labels */
X				if (!(barlab = comm_lget()) && data_head.labels)
X					barlab = make_labl((double)j+first_element);
X				switch (gravity) {
X					case SOUTH: put_lab(xbase+pos+gw/2, ybase-5*(int)t->v_char/2, barlab, 0, gw);
X						break;
X					case NORTH: put_lab(xmaxp-pos-gw/2, ymaxp+5*(int)t->v_char/2, barlab, 0, gw);
X						break;
X					case WEST:  put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-gw/2, barlab, 1, gw);
X						break;
X					case EAST:  put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+gw/2, barlab, 1, gw);
X						break;
X				}
X			}
X				
X			i++;
X			j++;
X			pos += incr*(xplot ? gw+sp : bw+ib);
X		}
X	}
X
X	return(1);
X}
X
Xdr_lbar(xplot)
XBOOLEAN xplot;
X/* draw layered barchart within given values and viewport */
X{
X	double unit, dummy;
X	vreal what;
X	double based = log_y ? log10(base) : base;
X	int bw, ib, of, i, j, k, pos, ibase, step, st_of, lbas, levels;
X	int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
X	int dirNS = !((int)gravity&1);
X	struct chunk *chn;
X	double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
X	double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
X	int incr = (b_clockwise ? 1 : -1);
X	int grunt = ((gravity == NORTH || gravity == EAST) ? 1 : -1);
X	struct dfile *f = &data_head;
X	double minv, maxv, full;
X	int LT, go_on;
X	char *common_label;
X
X	if (f->chunks == 1)
X		return(dr_abar(xplot));
X	
X	of = nint((xmaxp-xbase)*(1-MARGIN));
X	xbase += of; xmaxp -= of;
X	of = nint((ymaxp-ybase)*(1-MARGIN));
X	ybase += of; ymaxp -= of;
X
X	/* reserve space for labels */
X	switch (gravity) {
X		case SOUTH: ybase += 3*t->v_char/2;
X			break;
X		case NORTH: ymaxp -= 3*t->v_char/2;
X			break;
X		case EAST:  xmaxp -= 3*t->h_char/2;
X			break;
X		case WEST:  xbase += 3*t->h_char/2;
X			break;
X	}	
X
X	if (xplot)
X		unit = f->chunks + (f->chunks-1)*d_ib;
X	else
X		unit = f->points + (f->points-1)*d_ib;
X	if (!autoscale)
X		unit += d_ib;
X
X	bw = (dirNS ? xmaxp-xbase : ymaxp-ybase)/unit/2;
X	if ((double)bw/resolution > d_bw) {
X		bw = resolution*d_bw;
X		of = 3*(dirNS ? xmaxp-xbase : ymaxp-ybase)/4 - bw*unit/2;
X	}
X	else of = (dirNS ? xmaxp-xbase : ymaxp-ybase)/2;
X	if (!bw) return(0);
X
X	ib = nint(bw*d_ib);
X	if (!autoscale)
X		of += ib;
X	resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
X	step = resolution/(xplot ? f->points : f->chunks);
X	st_of = nint(2*(1-MARGIN)*step);
X	resolution = nint(step*(4*MARGIN-3));	/* resolution in pixels per one layer */
X	if (resolution < 2) return(0);	
X
X	/* initialize xptrs */
X	init_acrs();
X
X	levels = xplot ? data_head.points : data_head.chunks;
X	lbas = grunt==1 ? (levels-1)*step : 0;
X	for (f=data_head.dnxt, k=0, lbas+=st_of; k<levels; k++, lbas-=grunt*step) {
X
X		if (!xplot) {
X			minv = f->d_min;
X			maxv = f->d_max;
X			go_on = TRUE;
X		}
X		else
X			go_on = find_ran(&minv,&maxv,&dummy,&common_label);
X		
X		if (!xplot)
X			common_label = f->fname;
X		else if (common_label)
X			;
X		else if (data_head.labels)
X			common_label = make_labl((double)(k+first_element));
X		else
X			common_label = NULL;
X
X		(*t->linetype)(-2);
X		switch (gravity) {
X			case SOUTH:
X				(*t->move)(xbase,j=ybase+k*step);
X				(*t->vector)(xmaxp,j);
X				put_txt(xbase, j+(int)t->v_char, common_label, LEFT, 0);
X				break;
X			case NORTH:
X				(*t->move)(xbase,j=ymaxp-k*step);
X				(*t->vector)(xmaxp,j);
X				put_txt(xmaxp, j-(int)t->v_char, common_label, RIGHT, 0);
X				break;
X			case WEST:
X				(*t->move)(j=xbase+k*step,ybase);
X				(*t->vector)(j,ymaxp);
X				put_txt(j+(int)t->v_char, ymaxp, common_label, RIGHT, 1);
X				break;
X			case EAST:
X				(*t->move)(j=xmaxp-k*step,ybase);
X				(*t->vector)(j,ymaxp);
X				put_txt(j-(int)t->v_char, ybase, common_label, LEFT, 1);
X				break;
X		}
X
X		if (!go_on) continue;
X		
X		if (based<minv) minv=based;
X		if (based>maxv) maxv=based;
X		set_hm(minv, maxv);
X		if (!autoscale) switch (gravity) {
X			case SOUTH:
X				(void) do_axis(&minv,&maxv,(xmaxp+xbase)/2,xmaxp,lbas+ybase,lbas+ybase+resolution,TRUE);
X				break;
X			case NORTH:
X				(void) do_axis(&minv,&maxv,xbase,(xmaxp+xbase)/2,lbas+ybase,lbas+ybase+resolution,TRUE);
X				break;
X			case WEST:
X				(void) do_axis(&minv,&maxv,lbas+xbase,lbas+xbase+resolution,ybase,(ymaxp+ybase)/2,TRUE);
X				break;
X			case EAST:
X				(void) do_axis(&minv,&maxv,lbas+xbase,lbas+xbase+resolution,(ymaxp+ybase)/2,ymaxp,TRUE);
X		}
X		full = maxv-minv;
X		unit = resolution/full;
X		(*t->linetype)(-1);
X		switch (gravity) {
X			case SOUTH:
X				(*t->move)((xmaxp+xbase)/2,ibase=nint((based-minv)*unit)+lbas+ybase);
X				(*t->vector)(xmaxp,ibase);
X				break;
X			case NORTH:
X				(*t->move)((xmaxp+xbase)/2,ibase=nint((maxv-based)*unit)+ybase+lbas);
X				(*t->vector)(xbase,ibase);
X				break;
X			case WEST:
X				(*t->move)(ibase=nint((based-minv)*unit)+lbas+xbase,(ymaxp+ybase)/2);
X				(*t->vector)(ibase,ybase);
X				break;
X			case EAST:
X				(*t->move)(ibase=nint((maxv-based)*unit)+xbase+lbas,(ymaxp+ybase)/2);
X				(*t->vector)(ibase,ymaxp);
X				break;
X		}
X
X		if (b_clockwise) pos = of;
X		else pos = of + ((xplot ? data_head.chunks : data_head.points)-1)*(bw+ib);
X
X		/* put bottom-row labels (there is no better time to do that ... unfortunately */
X		if (!k) {
X			if (xplot)
X				f = data_head.dnxt;
X			for (i=0; i<(xplot ? data_head.chunks : data_head.points); i++, pos+=incr*(bw+ib)) {
X				if (xplot) {
X					common_label = f->fname;
X					f = f->dnxt;
X				}
X				else if (!(common_label = comm_lget()) && data_head.labels)
X					common_label = make_labl((double)i+first_element);
X				switch (gravity) {
X					case SOUTH: put_lab(xbase+pos+bw/2, ybase-(int)t->v_char, common_label, 0, bw);
X						break;
X					case NORTH: put_lab(xmaxp-pos-bw/2, ymaxp+(int)t->v_char, common_label, 0, bw);
X						break;
X					case WEST:  put_lab(xbase-(int)t->h_char, ymaxp-pos-bw/2, common_label, 1, bw);
X						break;
X					case EAST:  put_lab(xmaxp+(int)t->h_char, ybase+pos+bw/2, common_label, 1, bw);
X						break;
X				}
X			}
X			if (b_clockwise) pos = of;
X			else pos = of + ((xplot ? data_head.chunks : data_head.points)-1)*(bw+ib);
X		}
X
X		if (xplot) 
X			for (j=0, f=data_head.dnxt; f; j++, f=f->dnxt, pos+=incr*(bw+ib)) {
X				if (across[j].chnp && (what=across[j].chnp->dval[across[j].vindex]) != VERYLARGE) {
X					if (f->makeHL == HL_MIN && what == f->d_min ||
X						f->makeHL == HL_MAX && what == f->d_max ||
X						f->makeHL == k ||
X						data_head.makeHL == HL_MIN && what == data_head.d_min ||
X						data_head.makeHL == HL_MAX && what == data_head.d_max ||
X						data_head.makeHL == k)
X						(*t->linetype)(-1);
X					else
X						(*t->linetype)(j);
X					switch (gravity) {
X						case SOUTH: put_bar(xbase+pos,ibase, bw,nint((what-based)*unit),0);
X							break;
X						case NORTH: put_bar(xmaxp-pos,ibase,-bw,nint((based-what)*unit),0);
X							break;
X						case WEST:  put_bar(ibase,ymaxp-pos-bw,nint((what-based)*unit), bw,1);
X							break;
X						case EAST:  put_bar(ibase,ybase+pos+bw,nint((based-what)*unit),-bw,1);
X							break;
X					}
X				}
X				if (++across[j].vindex == across[j].chnp->used) {
X					across[j].vindex = 0;
X					across[j].chnp = across[j].chnp->next;
X				}
X			}
X		else {
X			(*t->linetype)(LT=0);
X			for (chn=f->data, i=0, j=0; chn; ) {
X				if (i==chn->used) {
X					i = 0;
X					chn = chn->next;
X					continue;
X				}
X				if ((what=chn->dval[i]) != VERYLARGE) {
X					if (f->makeHL == HL_MIN && what == f->d_min ||
X						f->makeHL == HL_MAX && what == f->d_max ||
X						f->makeHL == j ||
X						data_head.makeHL == HL_MIN && what == data_head.d_min ||
X						data_head.makeHL == HL_MAX && what == data_head.d_max ||
X						data_head.makeHL == j)
X						(*t->linetype)(LT=-1);
X					switch (gravity) {
X						case SOUTH: put_bar(xbase+pos,ibase, bw,nint((what-based)*unit),0);
X							break;
X						case NORTH: put_bar(xmaxp-pos,ibase,-bw,nint((based-what)*unit),0);
X							break;
X						case WEST:  put_bar(ibase,ymaxp-pos-bw,nint((what-based)*unit), bw,1);
X							break;
X						case EAST:  put_bar(ibase,ybase+pos+bw,nint((based-what)*unit),-bw,1);
X							break;
X					}
X					if (LT != 0) (*t->linetype)(LT=0);
X				}
X				i++;
X				j++;
X				pos += incr*(bw+ib);
X			}
X			f = f->dnxt;
X		}                           
X	}
X
X	return(1);
X}
X
Xdr_sbar(xplot)
XBOOLEAN xplot;
X{
X	double unit;
X	vreal what;
X	double based = log_y ? log10(base) : base;
X	int bw, ib, of, i, j, k, pos, ibase;
X	int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
X	int dirNS = !((int)gravity&1);
X	struct chunk *chn;
X	double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
X	double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
X	int incr = (b_clockwise ? 1 : -1), adit;
X	struct dfile *f = &data_head;
X	double minv=VERYLARGE, maxv=-VERYLARGE, full;
X	int *bumper, LT;
X	char labs[200];
X
X	if (xplot && f->chunks == 1) 
X		return(dr_abar(xplot));
X
X	init_acrs();
X	
X	if (xplot) 
X		for (j=0; j<data_head.points; j++) {
X			double a1=based, a2=based;
X			for (i=0; i<data_head.chunks; i++) {
X				if (!across[i].chnp) continue;
X				if ((what=across[i].chnp->dval[across[i].vindex]) != VERYLARGE) {
X					if (what<based) a1-=fabs(what);
X					if (what>based) a2+=fabs(what);
X				}
X				if (++across[i].vindex == across[i].chnp->used) {
X					across[i].vindex = 0;
X					across[i].chnp = across[i].chnp->next;
X				}
X			}
X			if (a1<minv) minv=a1;
X			if (a2>maxv) maxv=a2;
X		}
X	else
X		for (f=data_head.dnxt; f; f=f->dnxt) {
X			double a1=based, a2=based;
X			chn=f->data, i=0;
X			while (chn) {
X				if (i==chn->used) {
X					chn=chn->next;
X					i=0;
X					continue;
X				}
X				else if (chn->dval[i] != VERYLARGE)
X					if (chn->dval[i]<based) a1-=fabs(chn->dval[i]);
X					else if (chn->dval[i]>based) a2+=fabs(chn->dval[i]);
X				i++;
X			}
X			if (a1<minv) minv=a1;
X			if (a2>maxv) maxv=a2;
X		}
X
X	if (minv>based) minv=based;
X	if (maxv<based) maxv=based;
X	set_hm(minv, maxv);
X
X    of = nint((xmaxp-xbase)*(1-MARGIN));
X	xbase += of; xmaxp -= of;
X	of = nint((ymaxp-ybase)*(1-MARGIN));
X	ybase += of; ymaxp -= of;
X
X	/* reserve space for labels */
X	i = 2;
X	switch (gravity) {
X		case SOUTH: ybase += i*t->v_char, ymaxp -= t->v_char;
X			break;
X		case NORTH: ybase += t->v_char, ymaxp -= i*t->v_char;
X			break;
X		case EAST:  xbase += (howmuch+1)*t->h_char, xmaxp -= i*t->h_char;
X			break;
X		case WEST:  xbase += i*t->h_char, xmaxp -= (howmuch+1)*t->h_char;
X			break;
X	}
X
X	if (autoscale)
X		adit = 0;
X	else
X		adit = do_axis(&minv,&maxv,xbase,xmaxp,ybase,ymaxp,FALSE);
X	full = maxv-minv;
X
X	if (xplot)
X		unit = data_head.points + (data_head.points-1)*d_ib;
X	else
X		unit = data_head.chunks + (data_head.chunks-1)*d_ib;
X	if (!autoscale)
X		unit += d_ib;
X	
X	bw = ((dirNS ? xmaxp-xbase : ymaxp-ybase)-adit)/unit;
X	if ((double)bw/resolution > d_bw) {
X		bw = resolution*d_bw;
X		of = ((dirNS ? xmaxp-xbase : ymaxp-ybase) - adit - bw*unit)/2 + adit;
X	}
X	else of = adit;
X	if (!bw) return(0);
X	ib = nint(bw*d_ib);
X	if (!autoscale)		/* make space between axis and bar */
X		of += ib;
X
X	resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
X	unit = resolution/full;
X
X	(*t->linetype)(-1);
X	switch (gravity) {
X		case NORTH:
X			(*t->move)(xbase,ibase=nint((maxv-based)*unit)+ybase);
X			(*t->vector)(xmaxp-adit,ibase);
X			break;
X		case SOUTH:
X			(*t->move)(xbase+adit,ibase=nint((based-minv)*unit)+ybase);
X			(*t->vector)(xmaxp,ibase);
X			break;
X		case WEST:
X			(*t->move)(ibase=nint((based-minv)*unit)+xbase,ybase);
X			(*t->vector)(ibase,ymaxp-adit);
X			break;
X		case EAST:
X			(*t->move)(ibase=nint((maxv-based)*unit)+xbase,ybase+adit);
X			(*t->vector)(ibase,ymaxp);
X			break;
X	}
X
X	if (xplot)
X		for (f=data_head.dnxt, i=0; f; i++, f=f->dnxt) {
X			across[i].chnp = f->data;
X			across[i].vindex = 0;
X		}
X
X	(*t->linetype)(LT=0);
X	if (b_clockwise) pos = of;
X	else pos = of + ((xplot ? data_head.points : data_head.chunks)-1)*(bw+ib);
X	for (j=0, f=data_head.dnxt; j<(xplot?data_head.points:data_head.chunks); pos+=incr*(bw+ib), j++) {
X		int above=ibase, below=ibase, aux, labfound = 1;
X		BOOLEAN sense = TRUE;
X		char *common_label = NULL, *chaux;
X		double bsum1 = -VERYLARGE, bsum2 = -VERYLARGE;
X		i = k = 0;
X		if (!xplot) chn=f->data;
X		else f=data_head.dnxt, k=j;
X		do {
X			if (xplot) {
X				if (!across[i].chnp) what = VERYLARGE;
X				else {
X					what = across[i].chnp->dval[across[i].vindex];
X					if (labfound && across[i].chnp->vlbl && (chaux = across[i].chnp->vlbl[across[i].vindex]))
X						if (!common_label)	/* first found */
X							common_label = chaux;
X						else
X							labfound = !strcmp(common_label,chaux);
X					if (++across[i].vindex == across[i].chnp->used) {
X						across[i].vindex = 0;
X						across[i].chnp = across[i].chnp->next;
X					}
X				}
X				if (++i == data_head.chunks) sense=FALSE;
X			}
X			else {
X				if (i==chn->used) {
X					i=0;
X					sense = (chn=chn->next) != NULL;
X					continue;
X				}
X				what = chn->dval[i++];
X			}
X			if (what != VERYLARGE && what != based) {
X				if (f->makeHL == HL_MIN && what == f->d_min ||
X					f->makeHL == HL_MAX && what == f->d_max ||
X					f->makeHL == k ||
X					data_head.makeHL == HL_MIN && what == data_head.d_min ||
X					data_head.makeHL == HL_MAX && what == data_head.d_max ||
X					data_head.makeHL == k)
X					(*t->linetype)(LT=-1);
X				else if (xplot) (*t->linetype)(j);
X				if (what>based) bumper = &above, aux=1;
X				else bumper = &below, aux=-1;
X				if (what >= base) {
X					what = fabs(what);
X					if (bsum1 == -VERYLARGE)
X						bsum1 = what;
X					else
X						bsum1 += what;
X				}
X				else  {
X					what = fabs(what);
X					if (bsum2 == -VERYLARGE)
X						bsum2 = what;
X					else
X						bsum2 += what;
X				}
X				switch (gravity) {
X					case SOUTH: put_bar(xbase+pos,*bumper, bw,aux*=nint(what*unit),0);
X						break;
X					case NORTH: put_bar(xmaxp-pos,*bumper,-bw,aux*=-nint(what*unit),0);
X						break;
X					case WEST:  put_bar(*bumper,ymaxp-pos-bw,aux*=nint(what*unit), bw,1);
X						break;
X					case EAST:  put_bar(*bumper,ybase+pos+bw,aux*=-nint(what*unit),-bw,1);
X						break;
X				}
X				*bumper += aux;
X				if (LT != 0) (*t->linetype)(LT=0);
X			}
X			if (xplot) f=f->dnxt;
X			else k++;
X		} while (sense);
X
X		labs[0] = '\0';
X		if (bsum1 != -VERYLARGE) 
X			strcpy(labs, make_labl(bsum1));
X		if (bsum2 != -VERYLARGE) {
X			if (*labs)
X				strcat(labs, "/");
X			strcat(labs, make_labl(bsum2));
X		}
X		if (!xplot)
X			common_label = f->fname;
X		else if (!common_label && data_head.labels)		/* no label found, create one */
X			common_label = make_labl((double)j+first_element);
X		else if (!labfound)								/* different labels */
X			common_label = NULL;
X		/* else coomon_label is the common label */
X		
X		switch (gravity) {
X			case SOUTH: put_lab(xbase+pos+bw/2, above+2*(int)t->v_char/3, labs, 0, bw);
X				put_lab(xbase+pos+bw/2, ybase-5*(int)t->v_char/2, common_label, 0, bw);
X				break;
X			case NORTH:	put_lab(xmaxp-pos-bw/2, above-2*(int)t->v_char/3, labs, 0, bw);
X				put_lab(xmaxp-pos-bw/2, ymaxp+5*(int)t->v_char/2, common_label, 0, bw);
X				break;
X			case WEST:	put_txt(above+(int)t->h_char, ymaxp-pos-bw/2, labs, LEFT, 0); 
X				put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-bw/2, common_label, 1, bw);
X				break;
X			case EAST:  put_txt(above-(int)t->h_char, ybase+pos+bw/2, labs, RIGHT, 0); 
X				put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+bw/2, common_label, 1, bw);
X				break;
X			}
X		if (!xplot)
X			f = f->dnxt;
X	}
X
X	return(1);
X}
X
SHAR_EOF
$TOUCH -am 0604152590 fstyles.i &&
chmod 0666 fstyles.i ||
echo "restore of fstyles.i failed"
set `wc -c fstyles.i`;Wc_c=$1
if test "$Wc_c" != "27072"; then
	echo original size 27072, current size $Wc_c
fi
# ============= futil.c ==============
echo "x - extracting futil.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > futil.c &&
X/* Fchart - futil.c */
X/*
X * Gnuplot code
X * Copyright (C) 1986, 1987, 1990   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 *   Fchart changes and additions:
X *       Piotr Filip Sawicki
X *
X * send your comments or suggestions to fs@uwasa.fi
X *
X */
X#include <ctype.h>
X#include <setjmp.h>
X#include <stdio.h>
X#include <errno.h>
X#include "plot.h"
X#include "fchart.h"
X
Xextern BOOLEAN screen_ok;
X	/* TRUE if command just typed; becomes FALSE whenever we
X		send some other output to screen.  If FALSE, the command line
X		will be echoed to the screen before the ^ error message. */
X
X#ifndef vms
X#ifndef __ZTC__
Xextern int errno, sys_nerr;
Xextern char *sys_errlist[];
X#endif
X#endif /* vms */
X
Xextern char input_line[];
Xextern struct lexical_unit token[];
Xextern jmp_buf env;	/* from plot.c */
X
X
X/*
X * equals() compares string value of token number t_num with str[], and
X *   returns TRUE if they are identical.
X */
Xequals(t_num, str)
Xint t_num;
Xchar *str;
X{
Xregister int i;
X
X	if (!token[t_num].is_token)
X		return(FALSE);				/* must be a value--can't be equal */
X	for (i = 0; i < token[t_num].length; i++) {
X		if (input_line[token[t_num].start_index+i] != str[i])
X			return(FALSE);
X		}
X	/* now return TRUE if at end of str[], FALSE if not */
X	return(str[i] == '\0');
X}
X
X
X
X/*
X * almost_equals() compares string value of token number t_num with str[], and
X *   returns TRUE if they are identical up to the first $ in str[].
X */
Xalmost_equals(t_num, str)
Xint t_num;
Xchar *str;
X{
Xregister int i;
Xregister int after = 0;
Xregister start = token[t_num].start_index;
Xregister length = token[t_num].length;
X
X	if (!token[t_num].is_token)
X		return(FALSE);				/* must be a value--can't be equal */
X	for (i = 0; i < length + after; i++) {
X		if (str[i] != input_line[start + i]) {
X			if (str[i] != '$')
X				return(FALSE);
X			else {
X				after = 1;
X				start--;	/* back up token ptr */
X				}
X			}
X		}
X
X	/* i now beyond end of token string */
X
X	return(after || str[i] == '$' || str[i] == '\0');
X}
X
X
X
Xisstring(t_num)
Xint t_num;
X{
X	
X	return(token[t_num].is_token &&
X		   (input_line[token[t_num].start_index] == '\'' ||
X		   input_line[token[t_num].start_index] == '\"'));
X}
X
X
Xisnumber(t_num)
Xint t_num;
X{
X	return(!token[t_num].is_token);
X}
X
X
X/* never used -- why ? 
Xisletter(t_num)
Xint t_num;
X{
X	return(token[t_num].is_token &&
X			(isalpha(input_line[token[t_num].start_index])));
X}
X	*/
X
X
X/*
X * copy_str() copies the string in token number t_num into str, appending
X *   a null.  No more than MAX_ID_LEN chars are copied.
X *
Xcopy_str(str, t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i = 0;
Xregister int start = token[t_num].start_index;
Xregister int count;
X
X	if ((count = token[t_num].length) > MAX_ID_LEN)
X		count = MAX_ID_LEN;
X	do {
X		str[i++] = input_line[start++];
X		} while (i != count);
X	str[i] = '\0';
X}
X *
X */
X
X/*
X * quote_str() does the same thing as copy_str, except it ignores the
X *   quotes at both ends.  This seems redundant, but is done for
X *   efficency.
X */
Xquote_str(str, t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i = 0;
Xregister int start = token[t_num].start_index + 1;
Xregister int count;
X
X	if ((count = token[t_num].length - 2) > MAX_LINE_LEN)
X		count = MAX_LINE_LEN;
X	if (count>0) do {
X		str[i++] = input_line[start++];
X		} while (i != count);
X	str[i] = '\0';
X}
X
X
X/*
X *	capture() copies into str[] the part of input_line[] which lies between
X *	the begining of token[start] and end of token[end].
X */
Xcapture(str,start,end)
Xchar str[];
Xint start,end;
X{
Xregister int i,e;
X
X	e = token[end].start_index + token[end].length;
X	for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
X		*str++ = input_line[i];
X	*str = '\0';
X}
X
X
X/*
X *	m_capture() is similar to capture(), but it mallocs storage for the
X *  string.
X */
Xm_capture(str,start,end)
Xchar **str;
Xint start,end;
X{
X	register int i,e;
X	register char *s;
X
X	if (*str)		/* previous pointer to malloc'd memory there */
X		free(*str);
X	e = token[end].start_index + token[end].length;
X	*str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
X	s = *str;
X	for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
X		*s++ = input_line[i];
X	*s = '\0';
X}
X
X/*
X *	m_quote_capture() is similar to m_capture(), but it removes
X *	quotes from either end if the string.
X */
Xm_quote_capture(str,start,end)
Xchar **str;
Xint start,end;
X{
X	register int i,e;
X	register char *s;
X
X	if (*str)		/* previous pointer to malloc'd memory there */
X		free(*str);
X	e = token[end].start_index + token[end].length-1;
X	*str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
X	s = *str;
X	for (i = token[start].start_index + 1; i < e && input_line[i] != '\0'; i++)
X		*s++ = input_line[i];
X	*s = '\0';
X}
X
X/* returns pointer to value of token - no checking. Bogus. Outcomented
Xconvert(val_ptr, t_num)
Xstruct value *val_ptr;
Xint t_num;
X{
X	*val_ptr = token[t_num].l_val;
X}
X	*/
X
X
X/* not used 
Xdisp_value(fp,val)
XFILE *fp;
Xstruct value *val;
X{
X		switch(val->type) {
X			case INT:
X				fprintf(fp,"%d",val->v.int_val);
X				break;
X			case CMPLX:
X				if (val->v.cmplx_val.imag != 0.0 )
X					fprintf(fp,"{%g, %g}",
X						val->v.cmplx_val.real,val->v.cmplx_val.imag);
X				else
X					fprintf(fp,"%g", val->v.cmplx_val.real);
X				break;
X			default:
X				int_error("unknown type in disp_value()",NO_CARET);
X		}
X}
X	*/
X
Xdouble
Xreal(tok)		/* returns the real part of val */
Xint tok;
X{
X	struct value *val = &token[tok].l_val;
X	if (!isnumber(tok))
X		int_error("number expected",tok);
X	switch(val->type) {
X		case INT:
X			return((double) val->v.int_val);
X			break;
X		case CMPLX:
X			return(val->v.cmplx_val.real);
X	}
X	int_error("unknown type in real()",NO_CARET);
X	/* NOTREACHED */
X}
X
X/*
Xstruct value *
Xcomplex(a,realpart,imagpart)
Xstruct value *a;
Xdouble realpart, imagpart;
X{
X	a->type = CMPLX;
X	a->v.cmplx_val.real = realpart;
X	a->v.cmplx_val.imag = imagpart;
X	return(a);
X}
X
X
Xstruct value *
Xinteger(a,i)
Xstruct value *a;
Xint i;
X{
X	a->type = INT;
X	a->v.int_val = i;
X	return(a);
X}
X*/
X
X
Xos_error(str,t_num)
Xchar str[];
Xint t_num;
X{
X#ifdef vms
Xstatic status[2] = {1, 0};		/* 1 is count of error msgs */
X#endif
X
Xregister int i;
X
X	/* reprint line if screen has been written to */
X
X	if (t_num != NO_CARET) {		/* put caret under error */
X		if (!screen_ok)
X			fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
X
X		for (i = 0; i < sizeof(PROMPT) - 1; i++)
X			(void) putc(' ',stderr);
X		for (i = 0; i < token[t_num].start_index; i++) {
X			(void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
X			}
X		(void) putc('^',stderr);
X		(void) putc('\n',stderr);
X	}
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X	fprintf(stderr,"%s\n",str);
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X#ifdef vms
X	status[1] = vaxc$errno;
X	sys$putmsg(status);
X	(void) putc('\n',stderr);
X#else
X#ifdef __ZTC__
X	fprintf(stderr,"error number %d\n\n",errno);
X#else
X	if (errno >= sys_nerr)
X		fprintf(stderr, "unknown errno %d\n\n", errno);
X	else
X		fprintf(stderr,"(%s)\n\n",sys_errlist[errno]);
X#endif
X#endif
X
X	longjmp(env, TRUE);	/* bail out to command line */
X}
X
X
Xint_error(str,t_num)
Xchar str[];
Xint t_num;
X{
Xregister int i;
X
X	/* reprint line if screen has been written to */
X
X	if (t_num != NO_CARET) {		/* put caret under error */
X		if (!screen_ok)
X			fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
X
X		for (i = 0; i < sizeof(PROMPT) - 1; i++)
X			(void) putc(' ',stderr);
X		for (i = 0; i < token[t_num].start_index; i++) {
X			(void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
X			}
X		(void) putc('^',stderr);
X		(void) putc('\n',stderr);
X	}
X
X	for (i = 0; i < sizeof(PROMPT) - 1; i++)
X		(void) putc(' ',stderr);
X	fprintf(stderr,"%s\n\n",str);
X
X	longjmp(env, TRUE);	/* bail out to command line */
X}
X
X
Xcheck_ranges(v,f)  /* check if two ranges are not overlapping */
Xstruct pair *v, *f;
X{
X	if (v->from == -1 && (!f || f->from == -1)) return(TRUE);  /* both undefined */
X	if (v->from != -1 && v->upto != -1 &&
X		v->from > v->upto) return(FALSE);  /* v range is empty */
X	if (!f) return(TRUE);  /* only v given, and it's OK */
X	if (f->from != -1 && f->upto != -1 &&
X		f->from > f->upto) return(FALSE);  /* f range is empty */
X	if (v->from == -1 || f->from == -1) return(TRUE);  /* only one defined, and it is OK */
X	/* further checking is so boring ... */
X	if (v->from < f->from) {  /* v (probably) to the left of f */
X		if (v->upto == -1 || v->upto >= f->from) return(FALSE);  /* overl. */
X	}
X	else if (v->from > f->from) {
X		if (f->upto == -1 || f->upto >= v->from) return(FALSE);
X	}
X	else return(FALSE);  /* both start in the same place */
X	return(TRUE);  /* otherwise OK */
X}
X
X			
X/* Lower-case the given string (DFK) */
X/* Done in place. */
Xvoid lower_case(s)
Xchar *s;
X{
X	register char *p = s;
X	
X	while (*p != '\0') {
X		if (isupper(*p))
X			*p = tolower(*p);
X		p++;
X	}
X}
X
X/* Squash spaces in the given string (DFK) */
X/* That is, reduce all multiple white-space chars to single spaces */
X/* Done in place. */
Xvoid squash_spaces(s)
Xchar *s;
X{
X	register char *r = s;     /* reading point */
X	register char *w = s;     /* writing point */
X	BOOLEAN space = FALSE;        /* TRUE if we've already copied a space */
X	
X	for (w = r = s; *r != '\0'; r++) {
X		if (isspace(*r)) {
X			/* white space; only copy if we haven't just copied a space */
X			if (!space) {
X				space = TRUE;
X				*w++ = ' ';
X			}               /* else ignore multiple spaces */
X		} else {
X			/* non-space character; copy it and clear flag */
X			*w++ = *r;
X			space = FALSE;
X		}
X	}
X	*w = '\0';                /* null terminate string */
X}
SHAR_EOF
$TOUCH -am 0604152590 futil.c &&
chmod 0666 futil.c ||
echo "restore of futil.c failed"
set `wc -c futil.c`;Wc_c=$1
if test "$Wc_c" != "10184"; then
	echo original size 10184, current size $Wc_c
fi
# ============= fversion.c ==============
echo "x - extracting fversion.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > fversion.c &&
X/* Fchart - fversion.c */
X/*
X *  Modified version of 1.1.0 gnuplot by Thomas Williams and Colin Kelley.
X *  "You may use this code as you wish if credit is given and this message
X *  is retained."
X *
X *  Our "use" of this code has been to add a terminal driver (att 3b1),
X *  improve the IBM-PC drivers using TURBO-C routines, throw in a
X *  different help system (the one we got didn't seem to work) and add
X *  the commands SET POLAR, SET OFFSETS, and PAUSE.
X *
X *  Files that were changed from the original 1.1.0 version:
X *  command.c, graphics.c, misc.c, plot.c, term.c and version.c.
X *
X *  The annoying problem with unixplot files not being redirected by
X *  the set output command was fixed and an ``init()'' routine was
X *  added to term.c to allow an implementation to detect the terminal
X *  type.  (Currently only used by TURBO-C and VMS.)  The file term.c
X *  was further changed by breaking it into a number of .TRM files
X *  (Makefile was changed accordingly).
X *
X *  A bug in do_plot() was fixed as well as a VMS bug that caused
X *  SET OUTPUT to fail.  A final departure from the original 1.1.0
X *  version was the addition of Jyrki Yli-Nokari's HP laser jet
X *  drivers to term.c.
X *
X *  John Campbell  CAMPBELL@NAUVAX.bitnet (3b1, polar, offsets, pause)
X *  Bill Wilson    WILSON@NAUVAX.bitnet   (TURBO-C IBM-PC drivers)
X *  Steve Wampler  ...!arizona!naucse!sbw (help system acquisition)
X *
X *
X *  Fchart code by Piotr Filip Sawicki 1990
X *
X *  Main changes to Gnuplot:
X *  changed misc.c, util.c, command.c, plot.c, version.c
X *  removed eval.c, internal.c, parse.c, setshow.c, standard.c graphics.c
X *  untouched scanner.c, term.c, *.trm, help.[ch], doc utility
X *  added fgraf.c fstyles.i fonts.c flblarr.c
X *
X */
Xchar version[] = "1.0 (2D only)";
Xchar date[] = "May 1990";
Xchar bug_email[] = "fs@uwasa.fi";
Xint  patchlevel = 0;
SHAR_EOF
$TOUCH -am 0604152590 fversion.c &&
chmod 0666 fversion.c ||
echo "restore of fversion.c failed"
set `wc -c fversion.c`;Wc_c=$1
if test "$Wc_c" != "1852"; then
	echo original size 1852, current size $Wc_c
fi
# ============= titlepage.ms ==============
echo "x - extracting titlepage.ms (Text)"
sed 's/^X//' << 'SHAR_EOF' > titlepage.ms &&
X.nr HM 3.2i
X.TL
XFCHART
X.br
XAn Interactive Chart Program
X.sp
X.AU
XPiotr Filip Sawicki
X.br
XIIUW, Warsaw
X.AI
Xfs@uwasa.fi
X\*(DY
X.br
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
XThis manual is for FCHART version 1.0.
X.AB no
X.AE
X.LP
X.nr HM 1.2i
SHAR_EOF
$TOUCH -am 0604152590 titlepage.ms &&
chmod 0666 titlepage.ms ||
echo "restore of titlepage.ms failed"
set `wc -c titlepage.ms`;Wc_c=$1
if test "$Wc_c" != "214"; then
	echo original size 214, current size $Wc_c
fi
# ============= titlepage.tex ==============
echo "x - extracting titlepage.tex (Text)"
sed 's/^X//' << 'SHAR_EOF' > titlepage.tex &&
X\documentstyle{article}
X\setlength{\textwidth}{6.25in}
X\setlength{\oddsidemargin}{0.5cm}
X\setlength{\topmargin}{-0.5in}
X\setlength{\textheight}{9in}
X\setlength{\parskip}{1ex}
X\setlength{\parindent}{0pt}
X\begin{document}
X
X\pagestyle{empty}
X   \rule{0in}{3in}
X   \begin{center}
X   {\huge\bf FCHART}\\
X   \vspace{3ex}
X   {\Large An Interactive Chart Program}\\
X   \vspace{2ex}
X   \large
X   Piotr Filip Sawicki \\
X   IIUW, Warsaw \\
X   \vspace{2ex}
X   \verb+fs@uwasa.fi+
X
X   \vfill
X   {\small This manual is for Fchart version 1.0.}
X
X   \end{center}
X\newpage
X
X\tableofcontents
X\newpage
X
X\setcounter{page}{1}
X\pagestyle{myheadings}
X\markboth{FCHART 1.0}{FCHART 1.0}
X
SHAR_EOF
$TOUCH -am 0604152590 titlepage.tex &&
chmod 0666 titlepage.tex ||
echo "restore of titlepage.tex failed"
set `wc -c titlepage.tex`;Wc_c=$1
if test "$Wc_c" != "662"; then
	echo original size 662, current size $Wc_c
fi
exit 0