[comp.sources.unix] v20i004: Relational database and graphing tools, Part01/03

rsalz@uunet.uu.net (Rich Salz) (09/19/89)

Submitted-by: hafro.is!gunnar (Gunnar Stefansson)
Posting-number: Volume 20, Issue 4
Archive-name: reldb/part01

This package includes the following tools:
    This is scat, a simple scattergram program, which we have found very
    useful for all sorts of simple line drawing, with possible labels etc.
    Scat writes plot(5) commands to the standard output.

    Math reads columnar data from the standard input and outputs a few
    summary statistics.

    The following plot(1) filters:
	xplot		-- X11
	hpglplot	-- HP GL
	graplot		-- GRAP

    and others.

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./reldb.src`
then
  mkdir ./reldb.src
  echo "mkdir ./reldb.src"
fi
if `test ! -s ./reldb.src/recode.c`
then
echo "writting ./reldb.src/recode.c"
cat > ./reldb.src/recode.c << '\Rogue\Monster\'
/* recode:

	Author: gunnar@hafro.is (early 1988)

	Recodes first column in data (std. inp) according to
	1st+2nd column in filename of argument list.
*/
#include <stdio.h>
#define MAXOLD 10000	/* old values must be in the range 0 thru MAXOLD */
#define MAXLIN 1000	/* maximum length of input line */
#define USE "Usage : recode codefile < datafile \n"
main(argc,argv)
int argc;
char *argv[];
{
	char	inplin[MAXLIN];
	char	head[MAXLIN];	/* header: first of code file, then data file */
	char	*ptr;		/* temporary char pointer--loops over head*/
	char	*nmptr;		/* point to name of new code variable in head */
	int	o,n;		/* old/new codes from codefile */
	int	code[MAXOLD];	/* code transformations */
	FILE	*fp,*fopen();

	if((fp=fopen(argv[1],"r"))==NULL)	/* open code file */
		errlog(USE);
	fgets(head,MAXLIN,fp);			/* header line from code file */
	fgets(inplin,MAXLIN,fp);		/* skip second line */
	code[0] = -1;
	while(fgets(inplin,MAXLIN,fp)!=NULL){
		if(sscanf(inplin,"%d%d",&o,&n)!=2)	/* get code data */
			errlog("Error in code-file\n");
		o++;
		if(o<0||o>=MAXOLD)
			errlog("Error - old value outside range in codefile\n");
		code[o]=n;			/* store code data */
	}
	fclose(fp);				/* done with code file */
	for(ptr=head;*ptr!='\t';ptr++)		/* skip name of old col*/
		;					/* from code file */
	nmptr= ++ptr;				/* points to new col name */
	while(*ptr!='\n')
		putchar(*ptr++);		/* put new code name */
	*ptr='\0';				/* end the name */
	putchar('\t');				/* end the first outcol.*/
	fgets(inplin,MAXLIN,stdin);		/* get old data header */
	fputs(inplin,stdout);			/* append to output line */
	for(ptr=nmptr;*ptr;ptr++)		/* output correct # dashes */
		putchar('-');
	putchar('\t');				/* and the tab */
	fgets(inplin,MAXLIN,stdin);		/* get the dataline of dashes */
	fputs(inplin,stdout);			/* append to above dashes */
	while(fgets(inplin,MAXLIN,stdin)!=NULL){/* read a data line */
		if(sscanf(inplin,"%d",&o)!=1)
			errlog("recode : cannot read code from dataline\n");
		o++;
		if(o<0||o>MAXOLD)
			errlog("recode : code in data outside range \n");
		printf("%d\t%s",code[o],inplin);
	}
}
errlog(s)
char	*s;
{
	fprintf(stderr,"%s",s);
	exit(1);
}

\Rogue\Monster\
else
  echo "will not over write ./reldb.src/recode.c"
fi
if `test ! -s ./reldb.src/regress.c`
then
echo "writting ./reldb.src/regress.c"
cat > ./reldb.src/regress.c << '\Rogue\Monster\'
/*
	Simple linear regression

	Input : A reldb file of the form :
	
		xname	yname
		-----	-----
		x1	y1
		x2	y2
		etc
		
	Usage : regress < datafile
	
	Output : to std. out, all sorts of regression statistics.

NOTE: regress in Gary Perlman's package is much better than this
and should be preferred

									*/

#include <stdio.h>
main(){
	char xname[30],yname[30];	/* variable names */
	char buf[60];

	int c;			/* to recieve errors from scanf */

	float x,y;		/* input vbls */

	double n,sumx,sumy,sumxx,sumyy,sumxy;	/* obvious meaning */
	double xbar,ybar;	/* ditto */
	double stdevx,stdevy;
	double ssxx,ssyy,ssxy;	/* sum of sq. deviations */
	double sstot,sse,ssreg;	/* the ss's in the anova table */
	double mstot,mse,msreg; /* the ms's ------------------- */
	double t,F;		/* t*t=F for testing slope =0 */
	double alpha,beta;	/* regression coefficients */
	double r,r2;		/* correlation & explnd variation */
	double sqrt();

	c= -1;
	while((xname[++c]=getchar())!='\t')	/* get name of x */
		;
	xname[c]='\0';
	c= -1;
	while((yname[++c]=getchar())!='\n')	/* get name of y */
		;
	yname[c]='\0';
	gets(buf,60);				/* skip 2nd reldb line */

	while((c=scanf("%f %f",&x,&y))!=EOF){
		n+=1.;sumx+=x;sumy+=y;sumxx+=x*x;sumyy+=y*y;sumxy+=x*y;
	}

	ssyy=sumyy-sumy*sumy/n;	/* prepare regression estimates */
	ssxx=sumxx-sumx*sumx/n;	/* so compute numerators for variances */
	ssxy=sumxy-sumx*sumy/n;	/* and covariances */
	xbar=sumx/n;		/* not to forget means */
	ybar=sumy/n;
	stdevx=sqrt(  ssxx/(n-1.));
	stdevy=sqrt(  ssyy/(n-1.));

	beta=ssxy/ssxx;		/* slope estimate */
	alpha=ybar-beta*xbar;   /* intercept -- */
	r=ssxy/sqrt(  ssxx*ssyy);
	r2=ssxy*ssxy/(ssxx*ssyy);

	sstot=ssyy;		/* now for the anova table */
	ssreg=beta*beta*ssxx;	/* compute the sums of squares, */
	sse=sstot-ssreg;	
	mstot=sstot/(n-1.);	/* the mean squares */
	mse=sse/(n-2.);
	msreg=ssreg/1.;
	F=msreg/mse;		/* and the F-value */

	printf("Number of observations %.0f\n",n);
	printf("Average of %s-values    %.2f,",xname,xbar);
	printf("\taverage of %s-values    %.2f .\n",yname,ybar);

	printf("Std. dev. in %s-values  %.2f, ",xname,stdevx); 	
	printf("\tstd. dev. in %s-values  %.2f .\n",yname,stdevy); 

	printf("Correlation coefficient between %s and %s : %.4f",xname,yname,r);
	printf("\tExplained variation %.2f\n",r2);
	printf("Estimated regression line : %s = ",yname);
	printf(" %.2f + %.2f * %s \n\n",alpha,beta,xname);

	printf("Anova table \n\n");
	printf("Source\t\t\tSS\t\tdf\t\tMS\t\tF\n");
	printf("------------------------------------------");
	printf("--------------------------------\n");
	printf("Regression \t %10.2f \t %10.2f \t %10.2f \t %10.2f\n",ssreg,1.,msreg,F);
	printf("Error\t\t %10.2f \t %10.2f \t %10.2f\n",sse,n-2.,mse);
	printf("------------------------------------------");
	printf("--------------------------------\n");
	printf("Total \t\t %10.2f \t %10.2f \t %10.2f\n",sstot,n-1.,mstot);
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/regress.c"
fi
if `test ! -s ./reldb.src/rename.sh`
then
echo "writting ./reldb.src/rename.sh"
cat > ./reldb.src/rename.sh << '\Rogue\Monster\'
#!/bin/sh 
#
# Shell script to rename columns in a reldb data file.
#
# Usage :  rename old1 new1 old2 new2 old3 new3 ...
#
# The script simply builds a (fairly complex) sed-command.
# The command is inserted into the string cmd and
# is later piped into the shell, along with the data.
# Note that echo will not work due to tab-expansion
cmd=sed
while(true)
do
	if [ X$1 != X ]
	then
		name1=$1
		name2=$2
		shift
		shift
		cmd="$cmd -e "\""1s/\\(	*\\)$name1\\(	*\\)/\\1$name2\\2/"\"
	else
		( cat <<xxxx==
$cmd
xxxx==
cat - )  | sh
		exit
	fi
done

\Rogue\Monster\
else
  echo "will not over write ./reldb.src/rename.sh"
fi
if `test ! -s ./reldb.src/see.sh`
then
echo "writting ./reldb.src/see.sh"
cat > ./reldb.src/see.sh << '\Rogue\Monster\'
#!/bin/sh
#
# Trivial implementation of "see"
#
cat -vte $1
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/see.sh"
fi
if `test ! -s ./reldb.src/sideview.sh`
then
echo "writting ./reldb.src/sideview.sh"
cat > ./reldb.src/sideview.sh << '\Rogue\Monster\'
#!/bin/sh
#
# sideview -- put a table on its "side" and view a record at a time

awk 'BEGIN{FS="	"}
NR==1{for(i=1;i<=NF;i++){
	ind[i]=$(i)
	}
     }
NR>2{      print "";print "Faersla nr : ",NR-2
 for(i=1;i<=NF;i++)
	printf("%10s  %s\n", ind[i],$(i))
    }' < $1
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/sideview.sh"
fi
if `test ! -s ./reldb.src/sorttable.sh`
then
echo "writting ./reldb.src/sorttable.sh"
cat > ./reldb.src/sorttable.sh << '\Rogue\Monster\'
#!/bin/sh
#
# sorttable -- sort a reldb table

trap "rm tmp$$ tmp1$$" 15 2 1 
opt="-t	"
col=""
file=""
sortcol=""
for i
do
case $1 in
	'-n')
		opt="$opt -n"
		shift
		;;
	'-f')
		file=$2
		shift
		shift
		;;
	*)
		col="$col $1"
		shift
		;;
esac
done

sed -n "1,2p
3,\$w tmp$$" < $1  | tee tmp1$$

read columns < tmp1$$

for i in $col
do
	colnr=0
	for j in $columns
	do
		if [ X$i  = X$j ]
		then
			sortcol="$sortcol +$colnr"
		fi
		colnr=`expr $colnr + 1`
	done	
done
sort $opt $sortcol tmp$$
rm tmp$$ tmp1$$


\Rogue\Monster\
else
  echo "will not over write ./reldb.src/sorttable.sh"
fi
if `test ! -s ./reldb.src/subtotal.c`
then
echo "writting ./reldb.src/subtotal.c"
cat > ./reldb.src/subtotal.c << '\Rogue\Monster\'
/* subtotal.c 

Usage: subtotal by by-columnlist on on-columnlist < reldb-table

Controls doing subtotals of the on-columns for each set of fixed
values of all the by-columns.

This program just scans its arguments and generates a 
new command of the form: project colnames | addup number,
where addup adds up the relevant columns (assuming they
are in a decent order - making life much simpler).

Revision history:
	Original author:
		gunnar@hafro.is (1986 ?)
	Revisions due to incorrect string handling:
		gunnar@hafro.is (April, 1989)
*/
#include <stdio.h>
#ifdef BSD
#include <sys/wait.h>
#endif
#include <strings.h>
#define MAXCMD 1000
main(argc,argv)
int	argc;
char	*argv[];
{
	char	command[MAXCMD];
	char	*usage="Usage : subtotal by b1 b2 b3 ... on d1 d2 d3 ... < file\n";
	char	*ptr=command;
	int	count=0;
	int	debug=0;

	++argv;
	if(!strcmp(*argv,"-d")){
		debug=9;	/* assume full debug wanted */
		fprintf(stderr,"subtotal-debug level 9 used\n");
		argc--;
		++argv;
	}
	if(strcmp(*argv,"by"))
		errlog(usage);
	argv++;
	argc--;
	argc--;
	if(debug)fprintf(stderr,"subtotal: setting up project command\n");
	strcpy(ptr,"project ");
	ptr+=strlen(ptr);
	while(strcmp(*argv,"on")){
		strcpy(ptr,*argv);
		if(debug)fprintf(stderr,"\tby-column:%s\n",*argv);
		ptr+=strlen(ptr);
		*ptr++=' ';
		count++;
		argc--;argv++;
		if(argc<=0)
			errlog(usage);
	}
	argv++;argc--;
	if(debug)fprintf(stderr,"subtotal: finishing project command\n");
	while(argc){
		strcpy(ptr,*argv);
		if(debug)fprintf(stderr,"\ton-column:%s\n",*argv);
		ptr+=strlen(ptr);
		*ptr++=' ';
		argc--;argv++;
	}
	if(debug){
		sprintf(ptr," | addup %d %d\n",debug,count);
		fprintf(stderr,"COMMAND:->%s<-\n",command);
	} else {
		sprintf(ptr," | addup %d\n",count);
	}
	system(command);
#ifdef BSD
	wait((union wait *)0);
#else
        wait(0);
#endif
	exit(0);
}
errlog(s)
char	*s;
{
	fprintf(stderr,"%s",s);
	exit(1);
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/subtotal.c"
fi
if `test ! -s ./reldb.src/union.sh`
then
echo "writting ./reldb.src/union.sh"
cat > ./reldb.src/union.sh << '\Rogue\Monster\'
#!/bin/sh
#
# Now this has to be one of the most trivial commands in the world:
#
# union -- concatanate two reldb tables, using Unix tools.
#
cat $1
shift
for i
do
	tail +3 <$i
done

\Rogue\Monster\
else
  echo "will not over write ./reldb.src/union.sh"
fi
if `test ! -s ./reldb.src/reldb`
then
echo "writting ./reldb.src/reldb"
cat > ./reldb.src/reldb << '\Rogue\Monster\'
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/reldb"
fi
if `test ! -s ./reldb.src/Makefile`
then
echo "writting ./reldb.src/Makefile"
cat > ./reldb.src/Makefile << '\Rogue\Monster\'
#
# BINDIR is where the binaries and scripts go. Note that a simple 'make'
# will also install. You'll want to define BINDIR as ../bin untill
# you know things work.
#
BINDIR=../bin
#
# Use -DBSD for all BSD-systems
#     -DSYSV for sysv-style systems
#
CFLAGS= -DDEBUG=0 -DBSD
BINARIES=$(BINDIR)/addcol \
	$(BINDIR)/addup \
	$(BINDIR)/check \
	$(BINDIR)/compute \
	$(BINDIR)/select \
	$(BINDIR)/count \
	$(BINDIR)/columnlist \
	$(BINDIR)/dataplotpre \
	$(BINDIR)/dbdict \
	$(BINDIR)/dbe.change \
	$(BINDIR)/dbe.add \
	$(BINDIR)/invert \
	$(BINDIR)/jointable \
	$(BINDIR)/math \
	$(BINDIR)/matrix \
	$(BINDIR)/mulregpre \
	$(BINDIR)/number \
	$(BINDIR)/pairpre \
	$(BINDIR)/plokk \
	$(BINDIR)/preplot \
	$(BINDIR)/project \
	$(BINDIR)/recode \
	$(BINDIR)/rename \
	$(BINDIR)/see \
	$(BINDIR)/sideview \
	$(BINDIR)/sorttable \
	$(BINDIR)/bplokk \
	$(BINDIR)/subtotal \
	$(BINDIR)/testdb \
	$(BINDIR)/union


# Note that "regress" is not installed, since the regress program
# of |Stat is much better, esp. with the "mulregpre" interface.
reldb : $(BINARIES)
	touch reldb
uninstall :	
	rm -f $(BINARIES)

$(BINDIR)/addup : addup.c
	cc $(CFLAGS) -o $(BINDIR)/addup addup.c -lm
$(BINDIR)/compute : compute.c
	cc $(CFLAGS) -o $(BINDIR)/compute compute.c -lm
$(BINDIR)/select : $(BINDIR)/compute
	ln $(BINDIR)/compute $(BINDIR)/select
$(BINDIR)/count : count.c
	cc $(CFLAGS) -o $(BINDIR)/count count.c -lm
$(BINDIR)/matrix : matrix.c
	cc $(CFLAGS) -o $(BINDIR)/matrix matrix.c -lm
$(BINDIR)/plokk : plokk.c
	cc $(CFLAGS) -o $(BINDIR)/plokk plokk.c -lm
$(BINDIR)/project : project.c
	cc $(CFLAGS) -o $(BINDIR)/project project.c -lm
$(BINDIR)/recode : recode.c
	cc $(CFLAGS) -o $(BINDIR)/recode recode.c -lm
$(BINDIR)/regress : regress.c
	cc $(CFLAGS) -o $(BINDIR)/regress regress.c -lm
$(BINDIR)/subtotal : subtotal.c
	cc $(CFLAGS) -o $(BINDIR)/subtotal subtotal.c -lm
$(BINDIR)/check : check.sh
	cp  check.sh $(BINDIR)/check
	chmod +x $(BINDIR)/check
$(BINDIR)/bplokk : bplokk.sh
	cp  bplokk.sh $(BINDIR)/bplokk
	chmod +x $(BINDIR)/bplokk
$(BINDIR)/columnlist : columnlist.sh
	cp  columnlist.sh $(BINDIR)/columnlist
	chmod +x $(BINDIR)/columnlist
$(BINDIR)/dataplotpre : dataplotpre.sh
	cp  dataplotpre.sh $(BINDIR)/dataplotpre
	chmod +x $(BINDIR)/dataplotpre
$(BINDIR)/dbdict : dbdict.sh
	cp  dbdict.sh $(BINDIR)/dbdict
	chmod +x $(BINDIR)/dbdict
$(BINDIR)/dbe.add : dbe.add.sh
	cp  dbe.add.sh $(BINDIR)/dbe.add
	chmod +x  $(BINDIR)/dbe.add
$(BINDIR)/dbe.change : dbe.change.sh
	cp  dbe.change.sh $(BINDIR)/dbe.change
	chmod +x  $(BINDIR)/dbe.change
$(BINDIR)/invert : invert.sh
	cp  invert.sh $(BINDIR)/invert
	chmod +x $(BINDIR)/invert
$(BINDIR)/jointable : jointable.sh
	cp  jointable.sh $(BINDIR)/jointable
	chmod +x $(BINDIR)/jointable
$(BINDIR)/math : math.sh
	cp  math.sh $(BINDIR)/math
	chmod +x $(BINDIR)/math
$(BINDIR)/mulregpre : mulregpre.sh
	cp  mulregpre.sh $(BINDIR)/mulregpre
	chmod +x $(BINDIR)/mulregpre
$(BINDIR)/number : number.sh
	cp  number.sh $(BINDIR)/number
	chmod +x $(BINDIR)/number
$(BINDIR)/pairpre : pairpre.sh
	cp  pairpre.sh $(BINDIR)/pairpre
	chmod +x $(BINDIR)/pairpre
$(BINDIR)/preplot : preplot.sh
	cp  preplot.sh $(BINDIR)/preplot
	chmod +x $(BINDIR)/preplot
$(BINDIR)/rename : rename.sh
	cp  rename.sh $(BINDIR)/rename
	chmod +x $(BINDIR)/rename
$(BINDIR)/see : see.sh
	cp  see.sh $(BINDIR)/see
	chmod +x $(BINDIR)/see
$(BINDIR)/sideview : sideview.sh
	cp  sideview.sh $(BINDIR)/sideview
	chmod +x $(BINDIR)/sideview
$(BINDIR)/sorttable : sorttable.sh
	cp  sorttable.sh $(BINDIR)/sorttable
	chmod +x $(BINDIR)/sorttable
$(BINDIR)/union : union.sh
	cp  union.sh $(BINDIR)/union
	chmod +x $(BINDIR)/union
$(BINDIR)/addcol : addcol.sh
	cp addcol.sh $(BINDIR)/addcol
	chmod +x $(BINDIR)/addcol
$(BINDIR)/testdb : testdb.sh
	cp testdb.sh $(BINDIR)/testdb
	chmod +x $(BINDIR)/testdb
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/Makefile"
fi
if `test ! -s ./reldb.src/flattotable.sh`
then
echo "writting ./reldb.src/flattotable.sh"
cat > ./reldb.src/flattotable.sh << '\Rogue\Monster\'
#!/bin/sh
#
# flattotable - convert files with tabs and spaces to reldb table,
#               where only one tab separates columns.
#
# Eliminates tabs/spaces at beginning and end of lines.

sed -e 's/^[ 	]*//' \
    -e 's/[ 	]*$//' \
    -e 's/[ 	][ 	]*/	/g'
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/flattotable.sh"
fi
if `test ! -s ./reldb.src/testdb.sh`
then
echo "writting ./reldb.src/testdb.sh"
cat > ./reldb.src/testdb.sh << '\Rogue\Monster\'
#!/bin/sh
#
# testdb -- user script for testing reldb programs.
#

RELDBDIR=/usr/local/src/Reldb/testdb

if [ ! -d $RELDBDIR ]
then
	echo "I can't seem to find the test data and programs"
	echo "Please edit my RELDBDIR variable properly"
	echo "(It is now set to $RELDBDIR, which is incorrect)"
	exit 1
fi

# Go home first - no need to clutter discs
cd
if [ ! -d testdb ]
then
	mkdir testdb
fi
cd testdb
PWD=`pwd`
echo Testing reldb programs in $PWD
echo "Copying programs and data - hold on ..."
cp $RELDBDIR/* .
echo "Running 'make' - this willl result in a number of .tmp-files"
make
echo "Feel free to examine the .tmp-files. If everything is"
echo "working properly, they should be identical to the"
echo "corresponding .res-files"
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/testdb.sh"
fi
if `test ! -d ./scat.src`
then
  mkdir ./scat.src
  echo "mkdir ./scat.src"
fi
if `test ! -s ./scat.src/Makefile`
then
echo "writting ./scat.src/Makefile"
cat > ./scat.src/Makefile << '\Rogue\Monster\'
BINDIR=../bin
OBJ=scat.o readdat.o  plttics.o pttxt.o trans.o recplot.o extplotlib.o
all: scat
scat : $(OBJ)
	cc -o scat $(OBJ)  -lplot
install: scat
	cp scat $(BINDIR)
clean: 
	rm -f scat $(OBJ)
\Rogue\Monster\
else
  echo "will not over write ./scat.src/Makefile"
fi
if `test ! -s ./scat.src/README`
then
echo "writting ./scat.src/README"
cat > ./scat.src/README << '\Rogue\Monster\'
This is scat, a simple scattergram program, which we have found very
useful for all sorts of simple line drawing, with possible
labels etc. Scat writes plot(5) commands to the standard output.

1. 'make' compiles.
2. 'make install' installs.
3. 'scat -h' gives all the options.
4. See ../testgr for a number of graphics options.

5. Use the reldb programs to work on files like 'data'. This should
   not be done with options within scat.

Note that with the -E option, scat will generate plots where the
Y-axis label is "sideways", labels in the figure are centered etc.
For this to work, you need an extended plot-filter, such as the ones 
enclosed (in ../plot.src).

The enclosed Makefile assumes the user wants to link with the
plot-library, to generate plot(5) output. This is then normally
piped through the plot-filters (e.g. hpglplot or xplot, which are
enclosed. If none of the plot-stuff is available (notably in Xenix
and HP-UX), it should still be possible to link scat with hpglplot.o
or xplot.o and get a binary version of scat, which will work with that
single device. This is neither clean nor ideal, but it does provide
more usefulness.
\Rogue\Monster\
else
  echo "will not over write ./scat.src/README"
fi
if `test ! -s ./scat.src/defs.h`
then
echo "writting ./scat.src/defs.h"
cat > ./scat.src/defs.h << '\Rogue\Monster\'
#include <stdio.h>

#define MAXPTS	1500	/* max no of data points (lines in file) */
#define MAXCOLS	25	/* max no of data columns */
#define MAXTXT	100	/* max length of name of column */
\Rogue\Monster\
else
  echo "will not over write ./scat.src/defs.h"
fi
if `test ! -s ./scat.src/plttics.c`
then
echo "writting ./scat.src/plttics.c"
cat > ./scat.src/plttics.c << '\Rogue\Monster\'
#include "defs.h"
extern int debuglevel;
extern char *xformat;
extern char *yformat;

plot_tics(wxmin,wxmax,wymin,wymax,xmin,xmax,xdelta,ymin,ymax,ydelta)
double	xmin,xmax;		/* min, max of all x-values */
double	ymin,ymax;		/* min, max of all y-values */
double	xdelta,ydelta;		/* increment for x/y tick marks */
double  wxmin,wxmax,wymin,wymax;
{
	int i=0,j=0;
	int outx,outy;
	char number[80];
	double numlargeticks;
	double x, y;

	linemod("solid");
	if (debuglevel) {
		fprintf(stderr,"xformat= %s\n",xformat);	
		fprintf(stderr,"yformat= %s\n",yformat);	
	}

	labelplace("u");
	x=xmin;				/* x axis */
	sprintf(number,xformat,x);	/* char version of axis number */

	transf_data(wxmin,wymin,wxmax,wymax,x,ymin,&outx,&outy);
	move(outx,outy);
	transf_data(wxmin,wymin,wxmax,wymax,x,ymin-(ymax-ymin)*.03,&outx,&outy);
	cont(outx,outy);
	transf_data(wxmin,wymin,wxmax,wymax,x,ymin-(ymax-ymin)*.035,&outx,&outy);
	move(outx,outy);
	label(number);

	numlargeticks=(((xmax-xmin)/xdelta)/5);
	for(i=(int)numlargeticks;i--;){	/* large tick loop */
		for(j=5;j--;){		/* small tick loop */
			transf_data(wxmin,wymin,wxmax,wymax,x,ymin,&outx,&outy);
			move(outx,outy);	/* draw small tick */
			transf_data(wxmin,wymin,wxmax,wymax,x,ymin-(ymax-ymin)*.015,&outx,&outy);
	                cont(outx,outy);
			x+=xdelta;		/* x for next small tick */
		}
		transf_data(wxmin,wymin,wxmax,wymax,x,ymin,&outx,&outy);
		move(outx,outy);		/* next large tick */
		transf_data(wxmin,wymin,wxmax,wymax,x,ymin-(ymax-ymin)*.03,&outx,&outy);
		cont(outx,outy);
		transf_data(wxmin,wymin,wxmax,wymax,x,ymin-(ymax-ymin)*.035,&outx,&outy);
		move(outx,outy);
		sprintf(number,xformat,x);	/* put number at large tick */
		label(number);
	}

	labelplace("l");
	y=ymin;					/* y axis */
	sprintf(number,yformat,y);		/* string rep of # */
	transf_data(wxmin,wymin,wxmax,wymax,x,ymin,&outx,&outy);
	move(outx,outy);
	transf_data(wxmin,wymin,wxmax,wymax,xmin-(xmax-xmin)*.03,y,&outx,&outy);
	cont(outx,outy);
	transf_data(wxmin,wymin,wxmax,wymax,xmin-(xmax-xmin)*.035,y,&outx,&outy);
	move(outx,outy);
	label(number);
	numlargeticks=(((ymax-ymin)/ydelta)/5);
	for (i=(int)numlargeticks;i--;){
		for(j=5;j--;){
			transf_data(wxmin,wymin,wxmax,wymax,xmin,y,&outx,&outy);
			move(outx,outy);
		transf_data(wxmin,wymin,wxmax,wymax,xmin-(xmax-xmin)*.02,y,&outx,&outy);
		cont(outx,outy);
			y+=ydelta;
		}
		transf_data(wxmin,wymin,wxmax,wymax,xmin,y,&outx,&outy);
		move(outx,outy);
		transf_data(wxmin,wymin,wxmax,wymax,xmin-(xmax-xmin)*.03,y,&outx,&outy);
		cont(outx,outy);
		transf_data(wxmin,wymin,wxmax,wymax,xmin-(xmax-xmin)*.035,y,&outx,&outy);
		move(outx,outy);
		sprintf(number,yformat,y);
		label(number);
	}

}
\Rogue\Monster\
else
  echo "will not over write ./scat.src/plttics.c"
fi
if `test ! -s ./scat.src/pttxt.c`
then
echo "writting ./scat.src/pttxt.c"
cat > ./scat.src/pttxt.c << '\Rogue\Monster\'
#include <stdio.h>
#include "defs.h"
extern int debuglevel;
extern double spacekonst;

plot_texts(header,xlabel,ylabel,wxmin,wxmax,wymin,wymax,xmin,ymin,ymax)
char	*header;		/* figure caption */
char	*xlabel;		/* label for x axis */
char	*ylabel;		/* --------- y ---- */
double	xmin;		/* min of all x-values */
double	ymin,ymax;		/* min of all y-values */
double	wxmin,wxmax,wymin,wymax;/* window bounds */
{
	int outx, outy;
	
	if(debuglevel)fprintf(stderr,"In plot_texts\n");

	transf_data(wxmin,wymin,wxmax,wymax,(wxmin+wxmax)/2.,(wymax+ymax)/2.,&outx,&outy);
	labelplace("c");
	text(outx,outy,header);

	transf_data(wxmin,wymin,wxmax,wymax,(wxmin+wxmax)/2.,(wymin+ymin)/2.,&outx,&outy);
	labelplace("u");
	text(outx,outy,xlabel);

/*	transf_data(wxmin,wymin,wxmax,wymax,(wxmin+wxmin+wxmin+wxmin+xmin)/5.,(wymin+wymax)/2.,&outx,&outy);
*/
	transf_data(wxmin,wymin,wxmax,wymax,(wxmin+wxmin+xmin)/3.,(wymin+wymax)/2.,&outx,&outy);
	labelrotation(90);
	labelplace("o");
	text(outx,outy,ylabel);
	labelrotation(0);
}
\Rogue\Monster\
else
  echo "will not over write ./scat.src/pttxt.c"
fi
if `test ! -s ./scat.src/readdat.c`
then
echo "writting ./scat.src/readdat.c"
cat > ./scat.src/readdat.c << '\Rogue\Monster\'
#include <memory.h>
#include <string.h>
#include <strings.h>
#include "defs.h"

int     readline[]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
/* 1=data, 0=label-data */
extern int debuglevel;

read_data(numcols,numpts,names,pnames,pcol,lnames,lcol,drawline,data
,labeldata,missingvalue)

char	names[MAXCOLS][MAXTXT];	/* input : names of columns */
char    labeldata[MAXCOLS][MAXPTS][10];  /* input : label-data in columns */
char    *pnames[MAXCOLS];             /* don't draw lines for columns
                                        with this name */
char    *lnames[MAXCOLS];             /* name of column, which has
					label-data */
int	drawline[MAXCOLS];
int	pcol;
int	lcol;
int	*numcols;
int	*numpts;
int	missingvalue[MAXCOLS][MAXPTS];	/* 0=value is not missing from
					   input file, 1=value is missing 
					   from input file */
double	data[MAXCOLS][MAXPTS];	/* input : data in columns */
{
	int	c;		/* input character */
	int	i,ii;	
	int	jj;
	int	col= -1;	/* running column index */
	int	ldcol;	/* running column labeldata index */
	int	dcol;	/* running column data index */
	int	tmpcols;
	int	eol=0;
	int	fieldcount;
	char	inputline[1024];
	char	field[512];
	register char	*ip;
	register char	*ep;
	register int	n;

	double atof();

	if (debuglevel) fprintf(stderr,"In read_data\n");
	do{
		i=0;
		col++;
		while((c=getchar())!='\t'&&c!=' '&&c!='\n'&&c!=EOF)
			names[col][i++]=c;
		names[col][i]='\0';
	} while(c!='\n' && c!= EOF);
	if(c==EOF)exit(-1);
	*numcols= ++col;		/* store number of cols */
	while((c=getchar())!='\n');	/* skip line of minuses */

/* put 0 in drawline, if not to draw line for this column. */
	if(pcol > 0){
		for(i=0; i < pcol; i++)
			 for(col=1;col < *numcols;col++)
                                if(!strcmp(pnames[i],names[col]))
                                        drawline[col]=0;
	}

	if (debuglevel) {
		fprintf(stderr,"drawline after pcol\n");
		for (i=0; i < *numcols; i++)
			fprintf(stderr,"%d ",drawline[i]);
		fprintf(stderr,"\n");
	}

/* if label-column read the data in data- and labeldata-vectors */
	tmpcols= *numcols;

	if(lcol > 0){
		for(i=0; i < lcol; i++)
			 for(col=1;col < tmpcols;col++)
                                if(!strcmp(lnames[i],names[col])){
					drawline[col-1]=2;
					drawline[col]=2;
					readline[col]=0;
				}
	if (debuglevel) {
		fprintf(stderr,"drawline after lcol\n");
		for (i=0; i < *numcols; i++)
			fprintf(stderr,"%d ",drawline[i]);
		fprintf(stderr,"\nreadline after lcol\n");
		for (i=0; i < *numcols; i++)
			fprintf(stderr,"%d ",readline[i]);
		fprintf(stderr,"\n");
	}

/* fix the drawline vector */
		 for(col=1;col<tmpcols-1;col++)
			if(drawline[col] == 2 && drawline[col+1] == 2){
				for(jj=col+1; jj < tmpcols-1;jj++)
				    drawline[jj]=drawline[jj+1];
				}

	if (debuglevel) {
		fprintf(stderr,"drawline after fix\n");
		for (i=0; i < *numcols; i++)
			fprintf(stderr,"%d ",drawline[i]);
		fprintf(stderr,"\n");
	}
		*numcols=tmpcols-lcol;
		if (debuglevel) fprintf(stderr,"numcols= %d\n",*numcols);

	}
	i=0;

	while(gets(inputline)) {
	    ip = inputline;
	    fieldcount = 0;
            dcol=0;
            ldcol=0;
	    col = -1;

	    do {
		col++;
		ep = index(ip, '\t');
		if (ep == 0)
		    n = strlen(ip);
		else
		    n = ep - ip;
		if (n > 0) {
		    memcpy(field, ip, n);
		    field[n] = '\0';

                    if(readline[col]){
                        data[dcol][i]= atof(field);
			missingvalue[dcol][i]=0;
                        dcol++;
                        }
                    else{
                        strcpy(labeldata[ldcol][i],field);
                        ldcol++;
                        }

		    }
		else{
                    if(readline[col]){
			missingvalue[dcol][i]=1;
			dcol++;
		        }
		}
		ip = ep + 1;
	    } while(ep);
	i++;
	*numpts = i;
	}
}
\Rogue\Monster\
else
  echo "will not over write ./scat.src/readdat.c"
fi
if `test ! -s ./scat.src/scat.c`
then
echo "writting ./scat.src/scat.c"
cat > ./scat.src/scat.c << '\Rogue\Monster\'
#include <stdio.h>
#include "defs.h"
#define SPACECONST 1000.

int             drawline[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};	/* 0=no line, 1=line */

extern int      optind;
extern char    *optarg;
char            names[MAXCOLS][MAXTXT];	/* input : names of columns */
char            labeldata[MAXCOLS][MAXPTS][10];	/* input : label-data in
						 * columns */
char           *pnames[MAXCOLS];/* don't draw lines for columns with this
				 * name */
char           *lnames[MAXCOLS];/* name of column, which has label-data */

char           *optstr = "Eeicl:P:H:X:Y:F:w:x:y:d:l:L:";	/* list of options */
char           *header = "";	/* figure caption */
char           *xlabel = names[0];	/* label for x axis */
char           *ylabel = names[1];	/* --------- y ---- */
char           *plottertype = "hp300h";	/* type of output device */
char           *xformat = "%.1lf";
/* char	*yformat="%5.1lf"; */
char           *yformat = "%.1lf";
/*	"solid", "solid", "solid", "solid", "solid", /* -- was 1st line below - gs*/

char           *linetype[] = {
	"solid", "dotted", "longdashed", "shortdashed", "dotdashed",	/* change 14/6/89 - gs*/
	"solid", "dotted", "longdashed", "shortdashed", "dotdashed",
	"solid", "dotted", "longdashed", "shortdashed", "dotdashed",
	"solid", "dotted", "longdashed", "shortdashed", "dotdashed",
	"solid", "dotted", "longdashed", "shortdashed", "dotdashed",
};

static char    *help[] = {
	"Usage : scat [options]",
	"-x m,n,l	Bounds on x axis (min, max, interval   ",
	"-y m,n,l	Bounds on y axis (min, max, interval   ",
	"-w m,n,l,o	Window bounds  minx, miny, maxx,maxy   ",
	"-X text 	Text for X axis                        ",
	"-Y text  	Text for Y axis                        ",
	"-H text  	Figurecaption                          ",
	"-F \"x/y format\"	Format for numbers on x/y axis ",
	"-c       	Use colors                             ",
	"-e      	No erase                               ",
	"-E      	Use extended plot commands		",
	"-l name	Name of y column not to draw lines for ",
	"-L name	Name of label-column                   ",
	"-d number	Debug level                            ",
""};
char          **ptrhlp = help;

int             extended_plot = 0;

int             init_plotter = 1;
int             plotfil;
int             num_pens = 8;	/* number of pen in plotter */
int             numcols;	/* input : number of data-columns */
int             numpts;		/* ----------------- data pts */
int             pcol = 0;	/* number of columns, not to draw lines for */
int             lcol = 0;	/* number of label-columns in the inputdata */
int             debuglevel = 0;	/* level of debugging output */
int             outx, outy, outx1, outy1;	/* convert data to new coord.
						 * system */
int             plotdata[MAXCOLS][MAXPTS];	/* ditto  */
int             missingvalue[MAXCOLS][MAXPTS];	/* 1=value is missing from
						 * inputfile 0=value is not
						 * missing */
double          spaceconst = SPACECONST;
double          data[MAXCOLS][MAXPTS];	/* input : data in columns */
double          min[MAXCOLS];	/* min of data */
double          max[MAXCOLS];	/* max of data */
double          xmin = 0., xmax = 0.;	/* min, max of all x-values */
double          ymin = 0., ymax = 0.;	/* min, max of all y-values */
double          xdelta = 0., ydelta = 0.;	/* increment for x/y tick
						 * marks */
double          xrange = 0., yrange = 0.;	/* ranges of xy-values */
double          wxmin = 0., wxmax = 0.;	/* x-window bounds in x-scale */
double          wymin = 0., wymax = 0.;	/* y-window bounds in y-scale */
double          wx1 = 0., wx2 = SPACECONST;	/* Relative x-window bounds */
double          wy1 = 0., wy2 = SPACECONST;	/* relative y-window bounds */
main(argc, argv)
	int             argc;
	char          **argv;
{

	int             col, row, ldcol;	/* indices */
	int             c;
	int             werase = 1;	/* 0=no erase ; 1=erase */
	int             usecolor = 0;	/* 0=no color */
	int             optionx = 0;	/* option x not used */
	int             optiony = 0;	/* option y not used */

	while ((c = getopt(argc, argv, optstr)) != EOF) {
		switch (c) {
		case 'x':
			sscanf(optarg, "%lf,%lf,%lf", &xmin, &xmax, &xdelta);
			xrange = xmax - xmin;
			optionx = 1;
			break;
		case 'y':
			sscanf(optarg, "%lf,%lf,%lf", &ymin, &ymax, &ydelta);
			yrange = ymax - ymin;
			optiony = 1;
			break;
		case 'd':
			sscanf(optarg, "%d", &debuglevel);
			break;
		case 'i':
			init_plotter = 0;
			break;
		case 'E':
			extended_plot = 1;	/* no extended plot cmds */
			break;
		case 'e':
			werase = 0;	/* no erase */
			break;
		case 'c':
			usecolor = 1;	/* use color */
			break;
		case 'l':
			pnames[pcol] = optarg;
			pcol++;
			break;
		case 'L':
			lnames[lcol] = optarg;
			lcol++;
			break;
		case 'F':
			c = optarg[0];
			if (c == 'x')
				xformat = ++optarg;
			else
				yformat = ++optarg;
			break;
		case 'w':
			sscanf(optarg, "%lf,%lf,%lf,%lf", &wx1, &wy1, &wx2, &wy2);
			wx1 = wx1 * spaceconst;
			wx2 = wx2 * spaceconst;
			wy1 = wy1 * spaceconst;
			wy2 = wy2 * spaceconst;
			break;
		case 'X':
			xlabel = optarg;
			break;
		case 'Y':
			ylabel = optarg;
			break;
		case 'H':
			header = optarg;
			break;
		default:
			while (**ptrhlp)
				fprintf(stderr, "\t%s\n", *ptrhlp++);
			exit(-1);

		}
	}

	if (debuglevel) {
		fprintf(stderr, "Finished reading options\n");
		fprintf(stderr, "Read data\n");
		fprintf(stderr, "pcol= %d, lcol=%d\n", pcol, lcol);
	}
	read_data(&numcols, &numpts, names, pnames, pcol, lnames, lcol, drawline,
		  data, labeldata, missingvalue);

	if (debuglevel) {
		fprintf(stderr, "Finished reading data\n");
		for (row = 0; row < numpts; row++) {
			for (col = 0; col < lcol; col++)
				fprintf(stderr, "%s\t", labeldata[col][row]);
			fprintf(stderr, "\n");
		}
		for (row = 0; row < numpts; row++) {
			for (col = 0; col < numcols; col++)
				fprintf(stderr, "%lf\t", data[col][row]);
			fprintf(stderr, "\n");
		}
	}
	if (debuglevel)
		fprintf(stderr, "find min og max\n");
	/* find min and max of data */
	for (col = 0; col < numcols; col++) {
		max[col] = data[col][0];
		min[col] = data[col][0];
		for (row = 1; row < numpts; row++) {
			if (data[col][row] > max[col])
				max[col] = data[col][row];
			else if (data[col][row] < min[col])
				min[col] = data[col][row];
		}
	}

	if (optionx < 1) {
		xmin = min[0];	/* store x min and max */
		xmax = max[0];
		xrange = xmax - xmin;
		xdelta = xrange / 40.;
	}
	if (optiony < 1) {
		ymax = max[1];	/* initialize max/min of all yvals */
		ymin = min[1];
		for (col = 2; col < numcols; col++)
			if (max[col] > ymax)
				ymax = max[col];
			else if (min[col] < ymin)
				ymin = min[col];
		yrange = ymax - ymin;
		ydelta = yrange / 40.;
	}
	/* Enlarge outer frame */
	wxmin = xmin - 0.25 * xrange;
	wxmax = xmax + 0.10 * xrange;
	wymin = ymin - 0.25 * yrange;
	wymax = ymax + 0.15 * yrange;

	if (debuglevel) {
		fprintf(stderr, "wxmin= %lf and wxmax= %lf\n", wxmin, wxmax);
		fprintf(stderr, "wymin= %lf and wymax= %lf\n", wymin, wymax);
	}
	if (debuglevel)
		fprintf(stderr, "Opening plotter for output\n");
	openpl();
	if (werase)
		erase();
	space(0, 0, (int) spaceconst, (int) spaceconst);
	transf_data(wxmin, wymin, wxmax, wymax, wxmin, wymin, &outx, &outy);
	transf_data(wxmin, wymin, wxmax, wymax, wxmax, wymax, &outx1, &outy1);
	rectangle(outx, outy, outx1, outy1);
	transf_data(wxmin, wymin, wxmax, wymax, xmin, ymin, &outx, &outy);
	transf_data(wxmin, wymin, wxmax, wymax, xmax, ymax, &outx1, &outy1);
	rectangle(outx, outy, outx1, outy1);
	if (debuglevel)
		fprintf(stderr, "Finished initializing plotter\n");

	if (debuglevel)
		fprintf(stderr, "Converting data to new system\n");
	for (row = 0; row < numpts; row++)
		plotdata[0][row] = (int) ((wx2 - wx1) * (data[0][row] - wxmin) / (wxmax - wxmin) + wx1);
	for (col = 1; col < numcols; col++)
		for (row = 0; row < numpts; row++)
			plotdata[col][row] = (int) ((wy2 - wy1) * (data[col][row] - wymin) / (wymax - wymin) + wy1);

	if (debuglevel)
		fprintf(stderr, "Drawing figure\n");
	ldcol = 0;
	for (col = 1; col < numcols; col++) {
		if (usecolor)
			selectcolor((col - 1) % num_pens + 1);
		if (drawline[col] > 1) {
			labelplace("c");	/* center the label at the
						 * point */
			for (row = 0; row < numpts; row++)
				text(plotdata[0][row], plotdata[col][row], labeldata[ldcol][row]);
			ldcol++;
		} else if (drawline[col] > 0) {
			linemod(linetype[col - 1]);
			if (!missingvalue[col][0])
				point(plotdata[0][0], plotdata[col][0]);
			for (row = 1; row < numpts; row++) {
				if (!missingvalue[col][row]) {
					point(plotdata[0][row], plotdata[col][row]);
					if (!missingvalue[col][row - 1]) {
						move(plotdata[0][row - 1], plotdata[col][row - 1]);
						cont(plotdata[0][row], plotdata[col][row]);
					}
				}
			}
		} else {
			for (row = 0; row < numpts; row++)
				point(plotdata[0][row], plotdata[col][row]);
		}
	}

	if (debuglevel)
		fprintf(stderr, "Plotting tic-marks\n");
	plot_tics(wxmin, wxmax, wymin, wymax, xmin, xmax, xdelta, ymin, ymax, ydelta);

	if (debuglevel)
		fprintf(stderr, "Plotting texts\n");
	plot_texts(header, xlabel, ylabel, wxmin, wxmax, wymin, wymax, xmin, ymin, ymax);

	closepl();
}
\Rogue\Monster\
else
  echo "will not over write ./scat.src/scat.c"
fi
if `test ! -s ./scat.src/trans.c`
then
echo "writting ./scat.src/trans.c"
cat > ./scat.src/trans.c << '\Rogue\Monster\'
#include <stdio.h>
extern int debuglevel;
extern double spaceconst;
extern double wx1;
extern double wx2;
extern double wy1;
extern double wy2;


transf_data(wxmin,wymin,wxmax,wymax,inx,iny,outx,outy)
double wxmin,wymin,wxmax,wymax,inx,iny;
int   *outx,*outy;
{
  *outx=(int)((wx2-wx1)*(inx-wxmin)/(wxmax-wxmin)+wx1);
  *outy=(int)((wy2-wy1)*(iny-wymin)/(wymax-wymin)+wy1);
  if(debuglevel){
    fprintf(stderr,"inx= %lf iny= %lf\n",inx,iny);
    fprintf(stderr,"outx= %d & outy= %d\n",*outx,*outy);
  }
}

\Rogue\Monster\
else
  echo "will not over write ./scat.src/trans.c"
fi
if `test ! -s ./scat.src/recplot.c`
then
echo "writting ./scat.src/recplot.c"
cat > ./scat.src/recplot.c << '\Rogue\Monster\'
/* recplot.c -- some general routines for plotting 

Currently this is quite poor - only rectangle and text.
Someone should add higher-level routines, but of course these
can only be allowed to call the plot(3)-library (possibly with
extensions, which should then be placed in extplotlib.c, and
device-specific versions should be placed in the device-specific filters
(such as the enclosed hpglplot.c and xplot.c)

*/
#include <stdio.h>
extern int debuglevel;
extern int extended_plot;


rectangle(x,y,u,w)
int x,y,u,w;
{
	move(x,y);
	cont(x,w);
	cont(u,w);
	cont(u,y);
	cont(x,y);
}
text(x,y,labl)
int x,y;
char *labl;
{
	move(x,y);
	label(labl);
}
\Rogue\Monster\
else
  echo "will not over write ./scat.src/recplot.c"
fi
if `test ! -s ./scat.src/extplotlib.c`
then
echo "writting ./scat.src/extplotlib.c"
cat > ./scat.src/extplotlib.c << '\Rogue\Monster\'
/* extplotlib.c -- extensions to the plot-library
                   these routine generate plot(5) output
                   When linking directly to a device library (e.g. hpglplot.o),
                   which has the device-dependent version of
		   these routines, this should not be included.
*/
#include <stdio.h>
extern int debuglevel;
extern int extended_plot;


labelrotation(x)
int x;
{
	if(extended_plot){
		if (x == 90)
			printf("r v\n");  	/* vertical */
		else
			printf("r h\n");	/* horizontal */
	}
}
labelplace(s)
char *s;
{
	if(extended_plot){
		printf("u %s\n",s);
	}
}
selectcolor(x)
int x;
{
	if(extended_plot){
		printf("z %d\n",x);
	}
}

\Rogue\Monster\
else
  echo "will not over write ./scat.src/extplotlib.c"
fi
if `test ! -s ./scat.src/scat.starbase.c`
then
echo "writting ./scat.src/scat.starbase.c"
cat > ./scat.src/scat.starbase.c << '\Rogue\Monster\'
#include <stdio.h>
#include <starbase.c.h>

#define MAXPTS	1500	/* max no of data points (lines in file) */
#define MAXCOLS	25	/* max no of data columns */
#define MAXTXT	100	/* max length of name of column */
int	drawline[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* 0=no line, 1=line */

extern char *optarg;

main(argc,argv)
int	argc;
char	**argv;
{
	char	names[MAXCOLS][MAXTXT];	/* input : names of columns */
	char	*optstr="eicl:P:D:H:X:Y:w:x:y:";	/* list of options */
	char	*header="";		/* figure caption */
	char	*xlabel=names[0];	/* label for x axis */
	char	*ylabel=names[1];	/* --------- y ---- */
	char	*device="/dev/crt";	/* output device (/dev entry) */
	char	*plottertype="hp300h";	/* type of output device */
	static char	*help[]={
		"Usage : scat [options]",
		"-x m,n,l	Bounds on x axis (min, max, interval   ",
		"-y m,n,l	Bounds on y axis (min, max, interval   ",
		"-w m,n,l,o	Window bounds  minx, miny, maxx,maxy   ",
		"-X text 	Text for X axis                        ",
		"-Y text  	Text for Y axis                        ",
		"-H text  	Figurecaption                          ",
		"-P plottertype	Type of plotter (e.g. hp2622 og hpgl)  ",
		"-D device	Device (e.g. filename or /dev/plt7550) ",
		"-c       	Use colors                             ",
		"-i       	Don't initialize plotter               ",
		"-e      	No erase                               ",
		"-l name	Name of y column to draw lines for     ",
		""};
        char    **ptrhlp=help;

	int	init_plotter=INIT;
	int	plotfil;
	int	numcols;		/* input : number of columns */
	int	numpts;			/* ----------------- data pts */
	int	col,row;		/* indices */
	int	c;
	int	num_pts,y,yy;		/* */
	int	num_pens;
	int	werase=1;		/* 0=no erase ; 1=erase */
	int	usecolor=0;		/* 0=no color */

	float	plotvec[MAXPTS*2];	/* temp vec for plotting */
	float	ph_lim[2][3],res[3],p1[3],p2[3];

	double	data[MAXCOLS][MAXPTS];	/* input : data in columns */
	double	min[MAXCOLS];		/* min of data */
	double	max[MAXCOLS];		/* max of data */
	double	xmin,xmax;		/* min, max of all x-values */
	double	ymin,ymax;		/* min, max of all y-values */
	double	xdelta=0.,ydelta=0.;	/* increment for x/y tick marks */
	double	xrange=0.,yrange=0.;	/* ranges of xy-values */
	double	wxmin=0.,wxmax= 0.;	/* x-window bounds in x-scale */
	double	wymin=0.,wymax= 0.;	/* y-window bounds in y-scale */
	float	wx1=0., wx2=1.;		/* Relative x-window bounds */
	float	wy1=0., wy2=1.;		/* relative y-window bounds */


	read_data(&numcols,&numpts,names,data);
	find_bounds(numcols,numpts,data,min,max,&xmin,&xmax,&ymin,&ymax);
	
	xrange=xmax-xmin;
	xdelta=xrange/40.;
	yrange=ymax-ymin;
	ydelta=yrange/40.;
	while ((c = getopt(argc, argv, optstr)) != EOF) {
		switch ( c ) {
		case 'x': sscanf(optarg,"%lf,%lf,%lf",&xmin,&xmax,&xdelta);
			xrange=xmax-xmin;
	 		break; 
		case 'y': sscanf(optarg,"%lf,%lf,%lf",&ymin,&ymax,&ydelta);
			yrange=ymax-ymin;
	 		break; 
		case 'i': init_plotter=SPOOLED;
			break;
		case 'e': werase=0;		/* no erase */
			break;
		case 'c': usecolor=1;		/* use color */
			break;
		case 'l': for(col=1;col<numcols;col++)
				if(!strcmp(optarg,names[col]))
					drawline[col]=1;
		case 'w': sscanf(optarg,"%f,%f,%f,%f", &wx1,&wy1,&wx2,&wy2);
	 		break; 
		case 'X': xlabel = optarg; 		break; 
		case 'Y': ylabel = optarg;		break;
		case 'H': header = optarg;		break;
		case 'D': device = optarg;		break;
		case 'P': plottertype = optarg;		break;
		default:
			while(**ptrhlp)fprintf(stderr,"\t%s\n",*ptrhlp++);
			exit(-1);

		}
	}

	wxmin=xmin-0.25*xrange;
	wxmax=xmax+0.05*xrange;
	wymin=ymin-0.25*yrange;
	wymax=ymax+0.15*yrange;

	if((plotfil=gopen(device,OUTDEV,plottertype,init_plotter))== -1)exit(-1);
	set_p1_p2(plotfil,FRACTIONAL,wx1,wy1,0.,wx2,wy2,0.);
	vdc_extent(plotfil,(float)wxmin,(float)wymin,(float)0.,(float)wxmax,(float)wymax,(float)0.);
	clip_rectangle(plotfil,(float)wxmin,(float)wxmax,(float)wymin,(float)wymax);
	mapping_mode(plotfil,TRUE);
	interior_style(plotfil,INT_HOLLOW,TRUE);
	rectangle(plotfil,(float)wxmin,(float)wymin,(float)wxmax,(float)wymax);
	rectangle(plotfil,(float)xmin,(float)ymin,(float)xmax,(float)ymax);

	inquire_sizes(plotfil,ph_lim,res,p1,p2,&num_pens);
	for(col=1;col<numcols;col++){
		for(row=0;row<numpts;row++){
			plotvec[2*row]=data[0][row];
			plotvec[2*row+1]=data[col][row];
		}
		y=col+1;
		yy=col-1;
		if(usecolor)
			line_color_index(plotfil,y%num_pens);
		else
			line_type(plotfil,yy%7);
		if(drawline[col]) 
			polymarker2d(plotfil,plotvec,numpts,FALSE);
		else
			polyline2d(plotfil,plotvec,numpts,FALSE);
	}
	line_color_index(plotfil,1);
	plot_texts(plotfil,header,xlabel,ylabel,wxmin,wxmax,wymin,wymax,xmin,xmax,ymin,ymax);

	line_color_index(plotfil,1);
	plot_tics(plotfil,xmin,xmax,xdelta,ymin,ymax,ydelta,wxmin,wxmax,wymin,wymax);

	gclose(plotfil);
}
read_data(numcols,numpts,names,data)
char	names[MAXCOLS][MAXTXT];	/* input : names of columns */
int	*numcols;
int	*numpts;
double	data[MAXCOLS][MAXPTS];	/* input : data in columns */
{
	int	c;		/* input character */
	int	i;	
	int	col= -1;	/* running column index */

	do{
		i=0;
		col++;
		while((c=getchar())!='\t'&&c!=' '&&c!='\n'&&c!=EOF)
			names[col][i++]=c;
		names[col][i]='\0';
	} while(c!='\n' && c!= EOF);
	if(c==EOF)exit(-1);
	*numcols= ++col;		/* store number of cols */
	while((c=getchar())!='\n');	/* skip line of minuses */
	i=0;
	do {
		for(col=0;col < *numcols ; col++)
			if(scanf("%lf",&data[col][i])<=0)return;
		i++;
		*numpts=i;
	} while(1);
}
find_bounds(numcols,numpts,data,min,max,xmin,xmax,ymin,ymax)
int	numcols;		/* input : number of columns */
int	numpts;			/* ----------------- data pts */
double	data[MAXCOLS][MAXPTS];	/* input : data in columns */
double	min[MAXCOLS];	/* min on data */
double	max[MAXCOLS];	/* max of data */
double	*xmin,*xmax;	/* min,max of ALL x-values */
double	*ymin,*ymax;	/* min,max of ALL y-values */
{
	int	col;
	int	row;
	for(col=0;col<numcols;col++){
		max[col]=data[col][0];
		min[col]=data[col][0];
		for(row=1;row<numpts;row++){
			if(data[col][row]>max[col])
				max[col]=data[col][row];
			else if(data[col][row]<min[col])
				min[col]=data[col][row];
		}
	}
	*ymax=max[1];			/* initialize max/min of all y vals */
	*ymin=min[1];
	for(col=2;col<numcols;col++)
		if(max[col]>*ymax)*ymax=max[col];
		else if(min[col]<*ymin)*ymin=min[col];
	*xmin=min[0];			/* store x min and max */
	*xmax=max[0];
}
plot_texts(plotfil,header,xlabel,ylabel,wxmin,wxmax,wymin,wymax,xmin,xmax,ymin,ymax)
int	plotfil;
char	*header;		/* figure caption */
char	*xlabel;		/* label for x axis */
char	*ylabel;		/* --------- y ---- */
double	xmin,xmax;		/* min, max of all x-values */
double	ymin,ymax;		/* min, max of all y-values */
double	wxmin,wxmax,wymin,wymax;/* window bounds */
{
	text_alignment(plotfil,TA_CENTER,TA_TOP,0.0,0.0);	/* header */
	character_height(plotfil,.04*(wymax-wymin));
	text2d(plotfil,(wxmin+wxmax)/2.,wymax,
		header,VDC_TEXT,FALSE);
	text_alignment(plotfil,TA_CENTER,TA_TOP,0.0,0.0);	/* x-axis */
	character_height(plotfil,.04*(wymax-wymin));
	text2d(plotfil,(float)(wxmin+wxmax)/2.,(float)(wymin+ymin)/2.,
		xlabel,VDC_TEXT,FALSE);
	text_path(plotfil,PATH_DOWN);			/* y-axis */
	text_alignment(plotfil,TA_CENTER,TA_HALF,0.,0.);
	character_height(plotfil,.04*(wymax-wymin));
	text2d(plotfil,(wxmin+wxmin+xmin)/3.,(wymin+wymax)/2.,
		ylabel,VDC_TEXT,FALSE);
}
plot_tics(plotfil,xmin,xmax,xdelta,ymin,ymax,ydelta,wxmin,wxmax,wymin,wymax)
int	plotfil;
double	xmin,xmax;		/* min, max of all x-values */
double	ymin,ymax;		/* min, max of all y-values */
double	xdelta,ydelta;		/* increment for x/y tick marks */
double	wxmin,wxmax,wymin,wymax;/* window bounds */
{
	int i=0,j=0;
	char number[80];
	float numlargeticks;
	float x, y;

	text_path(plotfil,PATH_RIGHT);
	text_alignment(plotfil,TA_CENTER,TA_CONTINUOUS_VERTICAL,0.0,1.2);
	character_height(plotfil,.03*(wymax-wymin));
	line_type(plotfil,0);
	
	x=xmin;				/* x axis */
	sprintf(number,"%5.1lf",x);	/* char version of axis number */
	text2d(plotfil,x,ymin,number,VDC_TEXT,FALSE);
	numlargeticks=(((xmax-xmin)/xdelta)/5);
	for(i=numlargeticks;i--;){	/* large tick loop */
		for(j=5;j--;){		/* small tick loop */
			move2d(plotfil,x,ymin);	/* draw small tick */
			draw2d(plotfil,x,ymin+((ymax-ymin)*.015));
			x+=xdelta;		/* x for next small tick */
		}
		move2d(plotfil,x,ymin);		/* next large tick */
		draw2d(plotfil,x,ymin+((ymax-ymin)*.03));
		sprintf(number,"%5.1lf",x);	/* put number at large tick */
		text2d(plotfil,x,ymin,number,VDC_TEXT,FALSE);
	}
	text_alignment(plotfil,TA_CONTINUOUS_HORIZONTAL,TA_HALF,1.2,0.0);
	y=ymin;					/* y axis */
	sprintf(number,"%5.1lf",y);		/* string rep of # */
	text2d(plotfil,xmin,y,number,VDC_TEXT,FALSE);
	numlargeticks=(((ymax-ymin)/ydelta)/5);
	for (i=numlargeticks;i--;){
		for(j=5;j--;){
			move2d(plotfil,xmin,y);
			draw2d(plotfil,xmin+(xmax-xmin)*.02,y);
			y+=ydelta;
		}
		move2d(plotfil,xmin,y);
		draw2d(plotfil,xmin+(xmax-xmin)*.03,y);
		sprintf(number,"%5.1lf",y);
		text2d(plotfil,xmin,y,number,VDC_TEXT,FALSE);
	}
}



\Rogue\Monster\
else
  echo "will not over write ./scat.src/scat.starbase.c"
fi
if `test ! -d ./testdb`
then
  mkdir ./testdb
  echo "mkdir ./testdb"
fi
if `test ! -s ./testdb/data`
then
echo "writting ./testdb/data"
cat > ./testdb/data << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/data"
fi
if `test ! -s ./testdb/data.addcol`
then
echo "writting ./testdb/data.addcol"
cat > ./testdb/data.addcol << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/data.addcol"
fi
if `test ! -s ./testdb/subtotal.prog`
then
echo "writting ./testdb/subtotal.prog"
cat > ./testdb/subtotal.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test subtotal reldb program.
#
# Note that this also requires project and sorttable to work.
#
BINDIR=$1
INPUTFILE=$2
PATH=$BINDIR:$PATH
export PATH

# Test1 -- very simple test

COMMAND=subtotal
ARG1='w'
ARG2='y'
ARG="by $ARG1 on $ARG2"

echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE

echo;echo The following is the output from the command
echo "$COMMAND $ARG < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE
COMMAND=subtotal
ARG1='y z'
ARG2='u w v'
ARG="by $ARG1 on $ARG2"

echo ''; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE

echo;echo The following is the output from the command
echo "$COMMAND $ARG < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE

echo "Note that the input is not automatically sorted by
$COMMAND - however, the project command is run first, to reorder
the columns. To see explicitly how '$COMMAND $ARG' works, here 
is the output of 'project $ARG1 $ARG2 < $INPUTFILE' :"

project $ARG1 $ARG2 < $INPUTFILE
\Rogue\Monster\
else
  echo "will not over write ./testdb/subtotal.prog"
fi
if `test ! -s ./testdb/union.res`
then
echo "writting ./testdb/union.res"
cat > ./testdb/union.res << '\Rogue\Monster\'
The union takes two input files, e.g.
union.dat1:
col1	col2	col3
----	----	----
this	is	line1
line2	in	file1
line3	x	x
and union.dat2:
col1	col2	col3
----	----	----
this is	line1	in file2
line2	in	file2

The following is the output from the command
union union.dat1 union.dat2

col1	col2	col3
----	----	----
this	is	line1
line2	in	file1
line3	x	x
this is	line1	in file2
line2	in	file2
\Rogue\Monster\
else
  echo "will not over write ./testdb/union.res"
fi
if `test ! -s ./testdb/addcol.data`
then
echo "writting ./testdb/addcol.data"
cat > ./testdb/addcol.data << '\Rogue\Monster\'
x	y	z	v	u
-	-	-	-	-
0	9	2	3	4
1	2	2	3	4
2	3	4	5	6
2	3	5	6	7
4	5	6	7	8
\Rogue\Monster\
else
  echo "will not over write ./testdb/addcol.data"
fi
if `test ! -s ./testdb/compute.data`
then
echo "writting ./testdb/compute.data"
cat > ./testdb/compute.data << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/compute.data"
fi
if `test ! -s ./testdb/select.data`
then
echo "writting ./testdb/select.data"
cat > ./testdb/select.data << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	2	2	3	4	text1	6
5	1	2	3	4	text2	6
4	1	2	3	4	text3	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/select.data"
fi
if `test ! -s ./testdb/Makefile`
then
echo "writting ./testdb/Makefile"
cat > ./testdb/Makefile << '\Rogue\Monster\'
#
# Makefile to control testing of reldb programs.
#
# Change the BINDIR to reflect where the binaries are.
#
BINDIR=../bin
SUFFIXES=.diff .tmp .data .res
.SUFFIXES: $(SUFFIXES)
DIFFFILES=subtotal.diff addcol.diff compute.diff \
	jointable.diff  math.diff \
	project.diff select.diff union.diff recode.diff
.data.diff:
	$*.prog $(BINDIR) $*.data > $*.tmp
	-diff $*.tmp $*.res > $*.diff
all: $(DIFFFILES)
	@echo Done - check if any .diff-files are nonempty
	@ls -l $(DIFFFILES)
clean: 
	rm -f *.diff *.tmp tmp*
\Rogue\Monster\
else
  echo "will not over write ./testdb/Makefile"
fi
if `test ! -s ./testdb/addcol.prog`
then
echo "writting ./testdb/addcol.prog"
cat > ./testdb/addcol.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test addcol reldb program.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH

# Real simple - just add two columns
COMMAND="addcol www zzz" 
echo ; echo "Input data (file $INPUTFILE)" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND < $INPUTFILE"
echo
$COMMAND < $INPUTFILE
\Rogue\Monster\
else
  echo "will not over write ./testdb/addcol.prog"
fi
if `test ! -s ./testdb/project.data`
then
echo "writting ./testdb/project.data"
cat > ./testdb/project.data << '\Rogue\Monster\'
x	y	z	v	u	i	label_column
-	-	-	-	-	-	------------
0	1	2	3	4	6	*
1	2	3	4	5	7	**
2	3	4	5	6	8	***
3	4	5	6	7	9	v
4	5	6	7	8	10	vi
\Rogue\Monster\
else
  echo "will not over write ./testdb/project.data"
fi
if `test ! -s ./testdb/subtotal.data`
then
echo "writting ./testdb/subtotal.data"
cat > ./testdb/subtotal.data << '\Rogue\Monster\'
ex1	w	y	z	v	u	extra
---	-	-	-	-	-	-----
25	0	9	2	3	4	-3
4	0	2	2	3	4	-2
5	0	3	4	5	6	-3
5	2	3	4	6	7	-4
9	2	5	6	7	10	-3
9	2	5	6	120	8	-116
9	23	5	6	7	8	16
25	0	9	2	3	4	-3
25	2	9	2	5	6	-3
\Rogue\Monster\
else
  echo "will not over write ./testdb/subtotal.data"
fi
if `test ! -s ./testdb/compute.res`
then
echo "writting ./testdb/compute.res"
cat > ./testdb/compute.res << '\Rogue\Monster\'

Input data (compute.data):

x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10

The following is the output from the command
compute 'w=1;y=2*i;x=sqrt(i*z)' < compute.data

x	y	z	v	u	w	i
-	-	-	-	-	-	-
3.4641	12	2	3	4	1	6
4.58258	14	3	4	5	1	7
5.65685	16	4	5	6	1	8
6.7082	18	5	6	7	1	9
7.74597	20	6	7	8	1	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/compute.res"
fi
if `test ! -s ./testdb/project.prog`
then
echo "writting ./testdb/project.prog"
cat > ./testdb/project.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test project reldb program.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH
#Test project command
ARG="y z i label_column v"
set - $ARG


COMMAND=project
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo "(Note that the columns will not align on the screen when
a an entry is wider than 8 characters. This is OK since the delimiter
between fields is a single TAB character in all cases)"
echo;echo The following is the output from the command
echo "$COMMAND $* < $INPUTFILE"
echo
$COMMAND $* < $INPUTFILE
\Rogue\Monster\
else
  echo "will not over write ./testdb/project.prog"
fi
if `test ! -s ./testdb/compute.prog`
then
echo "writting ./testdb/compute.prog"
cat > ./testdb/compute.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test compute reldb program.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH
#Test compute command
#
COMMAND=compute
ARG='w=1;y=2*i;x=sqrt(i*z)'
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND '$ARG' < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE
\Rogue\Monster\
else
  echo "will not over write ./testdb/compute.prog"
fi
if `test ! -s ./testdb/project.res`
then
echo "writting ./testdb/project.res"
cat > ./testdb/project.res << '\Rogue\Monster\'

Input data (project.data):

x	y	z	v	u	i	label_column
-	-	-	-	-	-	------------
0	1	2	3	4	6	*
1	2	3	4	5	7	**
2	3	4	5	6	8	***
3	4	5	6	7	9	v
4	5	6	7	8	10	vi
(Note that the columns will not align on the screen when
a an entry is wider than 8 characters. This is OK since the delimiter
between fields is a single TAB character in all cases)

The following is the output from the command
project y z i label_column v < project.data

y	z	i	label_column	v
-	-	-	------------	-
1	2	6	*	3
2	3	7	**	4
3	4	8	***	5
4	5	9	v	6
5	6	10	vi	7
\Rogue\Monster\
else
  echo "will not over write ./testdb/project.res"
fi
if `test ! -s ./testdb/jointable.prog`
then
echo "writting ./testdb/jointable.prog"
cat > ./testdb/jointable.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test jointable reldb program.
#
# Note that jointable requires two input files - this
# cannot be handled by the Makefile, so we simply ignore
# the files the Makefile gives us.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH
#Test jointable command --  note that this requires sorttable to work also.
#echo Sorting file join.dat1
#sorttable < join.dat1 > tmp.joint.1
#sorttable < join.dat2 > tmp.joint.2
#echo Joining results of sort to get joined output:
#jointable tmp.joint.1 tmp.joint.2 
#rm tmp.joint.1 tmp.joint.2

COMMAND=sorttable
INPUTFILE=join.dat1
OUTPUTFILE=tmp.joint.1
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND  < $INPUTFILE > $OUTPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE > $OUTPUTFILE
cat $OUTPUTFILE

COMMAND=sorttable
INPUTFILE=join.dat2
OUTPUTFILE=tmp.joint.2
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND  < $INPUTFILE > $OUTPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE > $OUTPUTFILE
cat $OUTPUTFILE

COMMAND=jointable
FILE1=tmp.joint.1
FILE2=tmp.joint.2
echo;echo The following is the output from the command
echo "$COMMAND $FILE1 $FILE2"
echo
$COMMAND $FILE1 $FILE2

rm tmp.joint.1 tmp.joint.2
\Rogue\Monster\
else
  echo "will not over write ./testdb/jointable.prog"
fi
if `test ! -s ./testdb/select.res`
then
echo "writting ./testdb/select.res"
cat > ./testdb/select.res << '\Rogue\Monster\'

Input data (select.data):

x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	2	2	3	4	text1	6
5	1	2	3	4	text2	6
4	1	2	3	4	text3	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10

The following is the output from the command
select 'z>=3||y==2' < select.data

x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	2	2	3	4	text1	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
(The above select-command selects those lines in the
input file where either z is greater-than-or-equal-to 3 or
y is equal to 2. The word 'or' here (denoted by ||) means that
if either condition or both hold, then the corresponding line is printed).

Input data (select.data):

x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	2	2	3	4	text1	6
5	1	2	3	4	text2	6
4	1	2	3	4	text3	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10

The following is the output from the command
select 'z>=3&&y==2' < select.data

x	y	z	v	u	w	i
-	-	-	-	-	-	-
1	2	3	4	5	**	7
(The above select-command selects those lines in the
input file where z is greater-than-or-equal-to 3 AND
y is equal to 2. The word 'AND' here (denoted by &&) means that
only if both conditions hold, then the corresponding line is printed).
\Rogue\Monster\
else
  echo "will not over write ./testdb/select.res"
fi
if `test ! -s ./testdb/jointable.data`
then
echo "writting ./testdb/jointable.data"
cat > ./testdb/jointable.data << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/jointable.data"
fi
if `test ! -s ./testdb/join.dat1`
then
echo "writting ./testdb/join.dat1"
cat > ./testdb/join.dat1 << '\Rogue\Monster\'
x	y	z
-	-	-
10	1	2
9	2	3
8	3	4
7	4	5
6	5	6
\Rogue\Monster\
else
  echo "will not over write ./testdb/join.dat1"
fi
if `test ! -s ./testdb/join.dat2`
then
echo "writting ./testdb/join.dat2"
cat > ./testdb/join.dat2 << '\Rogue\Monster\'
x	v	u	w	i
-	-	-	-	-
5	3	4	*	6
6	4	5	**	7
7	5	6	***	8
8	6	7	v	9
4	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testdb/join.dat2"
fi
if `test ! -s ./testdb/subtotal.res`
then
echo "writting ./testdb/subtotal.res"
cat > ./testdb/subtotal.res << '\Rogue\Monster\'

Input data (subtotal.data):

ex1	w	y	z	v	u	extra
---	-	-	-	-	-	-----
25	0	9	2	3	4	-3
4	0	2	2	3	4	-2
5	0	3	4	5	6	-3
5	2	3	4	6	7	-4
9	2	5	6	7	10	-3
9	2	5	6	120	8	-116
9	23	5	6	7	8	16
25	0	9	2	3	4	-3
25	2	9	2	5	6	-3

The following is the output from the command
subtotal by w on y < subtotal.data

w	y
-	-
0	14
2	13
23	5
0	9
2	9

Input data (subtotal.data):

ex1	w	y	z	v	u	extra
---	-	-	-	-	-	-----
25	0	9	2	3	4	-3
4	0	2	2	3	4	-2
5	0	3	4	5	6	-3
5	2	3	4	6	7	-4
9	2	5	6	7	10	-3
9	2	5	6	120	8	-116
9	23	5	6	7	8	16
25	0	9	2	3	4	-3
25	2	9	2	5	6	-3

The following is the output from the command
subtotal by y z on u w v < subtotal.data

y	z	u	w	v
-	-	-	-	-
9	2	4	0	3
2	2	4	0	3
3	4	13	2	11
5	6	26	27	134
9	2	10	2	8
Note that the input is not automatically sorted by
subtotal - however, the project command is run first, to reorder
the columns. To see explicitly how 'subtotal by y z on u w v' works, here 
is the output of 'project y z u w v < subtotal.data' :
y	z	u	w	v
-	-	-	-	-
9	2	4	0	3
2	2	4	0	3
3	4	6	0	5
3	4	7	2	6
5	6	10	2	7
5	6	8	2	120
5	6	8	23	7
9	2	4	0	3
9	2	6	2	5
\Rogue\Monster\
else
  echo "will not over write ./testdb/subtotal.res"
fi
if `test ! -s ./testdb/README`
then
echo "writting ./testdb/README"
cat > ./testdb/README << '\Rogue\Monster\'
Some scripts to test the various reldb commands.
Type 'make' to run the test scripts, *.prog.

The expected output is already given in *.res. 

The 'make' command yields output which is in *.tmp.
This should be the same as in the *.res-files. Diff is
run by make to compare the sets. The diff-output is placed in
*.diff. These files should be empty, with the possible
exception of rounding errors (after the 6th digit).
\Rogue\Monster\
else
  echo "will not over write ./testdb/README"
fi
if `test ! -s ./testdb/select.prog`
then
echo "writting ./testdb/select.prog"
cat > ./testdb/select.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test select reldb program.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH
#Test select command
COMMAND=select
ARG='z>=3||y==2'
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND '$ARG' < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE
#
# Stick some explanations in:
#
echo "(The above $COMMAND-command selects those lines in the
input file where either z is greater-than-or-equal-to 3 or
y is equal to 2. The word 'or' here (denoted by ||) means that
if either condition or both hold, then the corresponding line is printed)."

# Second test
COMMAND=select
ARG='z>=3&&y==2'
echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE
echo;echo The following is the output from the command
echo "$COMMAND '$ARG' < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE
#
# Stick some explanations in:
#
echo "(The above $COMMAND-command selects those lines in the
input file where z is greater-than-or-equal-to 3 AND
y is equal to 2. The word 'AND' here (denoted by &&) means that
only if both conditions hold, then the corresponding line is printed)."
\Rogue\Monster\
else
  echo "will not over write ./testdb/select.prog"
fi
if `test ! -s ./testdb/jointable.res`
then
echo "writting ./testdb/jointable.res"
cat > ./testdb/jointable.res << '\Rogue\Monster\'

Input data (join.dat1):

x	y	z
-	-	-
10	1	2
9	2	3
8	3	4
7	4	5
6	5	6

The following is the output from the command
sorttable  < join.dat1 > tmp.joint.1

x	y	z
-	-	-
10	1	2
6	5	6
7	4	5
8	3	4
9	2	3

Input data (join.dat2):

x	v	u	w	i
-	-	-	-	-
5	3	4	*	6
6	4	5	**	7
7	5	6	***	8
8	6	7	v	9
4	7	8	vi	10

The following is the output from the command
sorttable  < join.dat2 > tmp.joint.2

x	v	u	w	i
-	-	-	-	-
4	7	8	vi	10
5	3	4	*	6
6	4	5	**	7
7	5	6	***	8
8	6	7	v	9

The following is the output from the command
jointable tmp.joint.1 tmp.joint.2

x	y	z	v	u	w	i
-	-	-	-	-	-	-
6	5	6	4	5	**	7
7	4	5	5	6	***	8
8	3	4	6	7	v	9
\Rogue\Monster\
else
  echo "will not over write ./testdb/jointable.res"
fi
if `test ! -s ./testdb/union.prog`
then
echo "writting ./testdb/union.prog"
cat > ./testdb/union.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test union reldb program.
#
# Note that union requires two input files - this
# cannot be handled by the Makefile, so we simply ignore
# the files the Makefile gives us.
#
BINDIR=$1
INPUTFILE=$2
PATH=$PATH:$BINDIR
export PATH

#Test union command 

COMMAND=union
FILE1=union.dat1
FILE2=union.dat2

echo "The union takes two input files, e.g.
$FILE1:"
cat $FILE1

echo "and $FILE2:"
cat $FILE2

echo;echo The following is the output from the command
echo "$COMMAND $FILE1 $FILE2"
echo
$COMMAND $FILE1 $FILE2

\Rogue\Monster\
else
  echo "will not over write ./testdb/union.prog"
fi
if `test ! -s ./testdb/union.dat1`
then
echo "writting ./testdb/union.dat1"
cat > ./testdb/union.dat1 << '\Rogue\Monster\'
col1	col2	col3
----	----	----
this	is	line1
line2	in	file1
line3	x	x
\Rogue\Monster\
else
  echo "will not over write ./testdb/union.dat1"
fi
if `test ! -s ./testdb/union.dat2`
then
echo "writting ./testdb/union.dat2"
cat > ./testdb/union.dat2 << '\Rogue\Monster\'
col1	col2	col3
----	----	----
this is	line1	in file2
line2	in	file2
\Rogue\Monster\
else
  echo "will not over write ./testdb/union.dat2"
fi
if `test ! -s ./testdb/union.data`
then
echo "writting ./testdb/union.data"
cat > ./testdb/union.data << '\Rogue\Monster\'
\Rogue\Monster\
else
  echo "will not over write ./testdb/union.data"
fi
if `test ! -s ./testdb/addcol.res`
then
echo "writting ./testdb/addcol.res"
cat > ./testdb/addcol.res << '\Rogue\Monster\'

Input data (file addcol.data)

x	y	z	v	u
-	-	-	-	-
0	9	2	3	4
1	2	2	3	4
2	3	4	5	6
2	3	5	6	7
4	5	6	7	8

The following is the output from the command
addcol www zzz < addcol.data

x	y	z	v	u	www	zzz
-	-	-	-	-	---	---
0	9	2	3	4
1	2	2	3	4
2	3	4	5	6
2	3	5	6	7
4	5	6	7	8
\Rogue\Monster\
else
  echo "will not over write ./testdb/addcol.res"
fi
if `test ! -s ./testdb/recode.prog`
then
echo "writting ./testdb/recode.prog"
cat > ./testdb/recode.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test recode reldb program.
#
#
BINDIR=$1
INPUTFILE=$2
PATH=$BINDIR:$PATH
export PATH

CODEFILE=recode.codes

COMMAND=recode
ARG="$CODEFILE"

echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE

echo ;echo "Code file ($CODEFILE):" ; echo
cat $CODEFILE

echo;echo The following is the output from the command
echo "$COMMAND $ARG < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE

\Rogue\Monster\
else
  echo "will not over write ./testdb/recode.prog"
fi
if `test ! -s ./testdb/recode.data`
then
echo "writting ./testdb/recode.data"
cat > ./testdb/recode.data << '\Rogue\Monster\'
ex1	w	y	z	v	u	extra
---	-	-	-	-	-	-----
25	0	9	2	3	4	-3
4	0	2	2	3	4	-2
5	0	3	4	5	6	-3
5	2	3	4	6	7	-4
9	2	5	6	7	10	-3
9	2	5	6	120	8	-116
9	23	5	6	7	8	16
25	0	9	2	3	4	-3
25	2	9	2	5	6	-3
\Rogue\Monster\
else
  echo "will not over write ./testdb/recode.data"
fi
if `test ! -s ./testdb/recode.codes`
then
echo "writting ./testdb/recode.codes"
cat > ./testdb/recode.codes << '\Rogue\Monster\'
ex1	new
---	---
1	20
2	21
3	22
4	23
5	24
9	25
25	0
\Rogue\Monster\
else
  echo "will not over write ./testdb/recode.codes"
fi
if `test ! -s ./testdb/math.data`
then
echo "writting ./testdb/math.data"
cat > ./testdb/math.data << '\Rogue\Monster\'
x	y	z	v
-	-	-	-
0	1	2	3
1		3	4
2	3	4	5
3	4	5	6
4	5	6	7
\Rogue\Monster\
else
  echo "will not over write ./testdb/math.data"
fi
if `test ! -s ./testdb/math.res`
then
echo "writting ./testdb/math.res"
cat > ./testdb/math.res << '\Rogue\Monster\'

Input data (math.data):

x	y	z	v
-	-	-	-
0	1	2	3
1		3	4
2	3	4	5
3	4	5	6
4	5	6	7

The following is the output from the command
math  < math.data

x	y	z	v	Type
-	-	-	-	----
5	4	5	5	Freq
10	13	20	25	Sum
2	3	4	5	Mean
1.58114	1.70783	1.58114	1.58114	Stddev
4	5	6	7	Maximum
0	1	2	3	Minimum
\Rogue\Monster\
else
  echo "will not over write ./testdb/math.res"
fi
if `test ! -s ./testdb/math.prog`
then
echo "writting ./testdb/math.prog"
cat > ./testdb/math.prog << '\Rogue\Monster\'
#!/bin/sh
#
# Shell script to test math reldb program.
#
#
BINDIR=$1
INPUTFILE=$2
PATH=$BINDIR:$PATH
export PATH


COMMAND=math
ARG=""

echo ; echo "Input data ($INPUTFILE):" ; echo
cat $INPUTFILE

echo;echo The following is the output from the command
echo "$COMMAND $ARG < $INPUTFILE"
echo
$COMMAND $ARG < $INPUTFILE

\Rogue\Monster\
else
  echo "will not over write ./testdb/math.prog"
fi
if `test ! -s ./testdb/recode.res`
then
echo "writting ./testdb/recode.res"
cat > ./testdb/recode.res << '\Rogue\Monster\'

Input data (recode.data):

ex1	w	y	z	v	u	extra
---	-	-	-	-	-	-----
25	0	9	2	3	4	-3
4	0	2	2	3	4	-2
5	0	3	4	5	6	-3
5	2	3	4	6	7	-4
9	2	5	6	7	10	-3
9	2	5	6	120	8	-116
9	23	5	6	7	8	16
25	0	9	2	3	4	-3
25	2	9	2	5	6	-3

Code file (recode.codes):

ex1	new
---	---
1	20
2	21
3	22
4	23
5	24
9	25
25	0

The following is the output from the command
recode recode.codes < recode.data

new	ex1	w	y	z	v	u	extra
---	---	-	-	-	-	-	-----
0	25	0	9	2	3	4	-3
23	4	0	2	2	3	4	-2
24	5	0	3	4	5	6	-3
24	5	2	3	4	6	7	-4
25	9	2	5	6	7	10	-3
25	9	2	5	6	120	8	-116
25	9	23	5	6	7	8	16
0	25	0	9	2	3	4	-3
0	25	2	9	2	5	6	-3
\Rogue\Monster\
else
  echo "will not over write ./testdb/recode.res"
fi
if `test ! -d ./testgr`
then
  mkdir ./testgr
  echo "mkdir ./testgr"
fi
if `test ! -s ./testgr/README`
then
echo "writting ./testgr/README"
cat > ./testgr/README << '\Rogue\Monster\'
Some sample uses of scat.

README
data.*		Some data files
t?		A few sample scat-commands. Run them with
		e.g. t1 | xplot =500x500+100+100
		or   t2 | plot -Ttek
		etc

Note that t4 uses extended plot(5)-commands.
\Rogue\Monster\
else
  echo "will not over write ./testgr/README"
fi
if `test ! -s ./testgr/t1`
then
echo "writting ./testgr/t1"
cat > ./testgr/t1 << '\Rogue\Monster\'
#!/bin/sh
#
# Very basic -- no options

scat < data.smpl
\Rogue\Monster\
else
  echo "will not over write ./testgr/t1"
fi
if `test ! -s ./testgr/data.smpl`
then
echo "writting ./testgr/data.smpl"
cat > ./testgr/data.smpl << '\Rogue\Monster\'
x	y
-	-
0	1
1	2
2	3
3	4
4	5
\Rogue\Monster\
else
  echo "will not over write ./testgr/data.smpl"
fi
if `test ! -s ./testgr/t2`
then
echo "writting ./testgr/t2"
cat > ./testgr/t2 << '\Rogue\Monster\'
#!/bin/sh
#
# Basic x,y-plot, but scaling axes

scat -x0,5,.5 -y 0,5,0.5 -H "Sample x/y-plot" < data.smpl
\Rogue\Monster\
else
  echo "will not over write ./testgr/t2"
fi
if `test ! -s ./testgr/t3`
then
echo "writting ./testgr/t3"
cat > ./testgr/t3 << '\Rogue\Monster\'
#!/bin/sh
# 
# Slightly more complex plot. Data contains 3 columns.
# Plot contains col2(z) vs col1(y) as a line, with col4(w) as labels
# at the points (col1,col3) or (v,y)
# 
# This is what the data looks like:
#
# y	z	v	w
# -	-	-	-
# 1	2	3	*
# 2	3	4	**
# 3	4	5	***
# 4	5	6	v
# 5	6	7	vi
scat \
	-X "X-axis" \
	-Y "Y-axis" \
	-x0,5,.5 \
	-y 0,10,1 \
	-L w \
	-H "Sample x/y-plot" \
	< data.3
#
# Note the use of -X and -Y to define axis labels.
# The Y-axis label is not rotated unless the -E option is added to
# the scat command-line. In this case, extended commands must be
# supported by the plot-filter used.
\Rogue\Monster\
else
  echo "will not over write ./testgr/t3"
fi
if `test ! -s ./testgr/data.3`
then
echo "writting ./testgr/data.3"
cat > ./testgr/data.3 << '\Rogue\Monster\'
y	z	v	w
-	-	-	-
1	2	3	*
2	3	4	**
3	4	5	***
4	5	6	v
5	6	7	vi
\Rogue\Monster\
else
  echo "will not over write ./testgr/data.3"
fi
if `test ! -s ./testgr/data.cmplx`
then
echo "writting ./testgr/data.cmplx"
cat > ./testgr/data.cmplx << '\Rogue\Monster\'
x	y	z	v	u	w	i
-	-	-	-	-	-	-
0	1	2	3	4	*	6
1	2	3	4	5	**	7
2	3	4	5	6	***	8
3	4	5	6	7	v	9
4	5	6	7	8	vi	10
\Rogue\Monster\
else
  echo "will not over write ./testgr/data.cmplx"
fi
if `test ! -s ./testgr/t4`
then
echo "writting ./testgr/t4"
cat > ./testgr/t4 << '\Rogue\Monster\'
#!/bin/sh
# 
# Input data (data.cmplx):
#
# x	y	z	v	u	w	i
# -	-	-	-	-	-	-
# 0	1	2	3	4	*	6
# 1	2	3	4	5	**	7
# 2	3	4	5	6	***	8
# 3	4	5	6	7	v	9
# 4	5	6	7	8	vi	10
#
# Draw two plots in the same window (or on same paper, etc).
#
# First plot is y vs x, with lines through the points and
# also labels w at the points. For this, the y-column must
# come twice (once for the line and once for the w's). The project and
# compute statements accomplish this.
project x y newy w < data.cmplx |
	compute 'newy=y' |
	scat \
		-H "First figure" \
		-X "Sample X axis" \
		-Y "Rotated Y" \
		-E \
		-Lw \
		-x 0,5,0.5 \
		-y 0,5,0.5 \
		-w 0,0,0.5,0.5

# Second plot has points (x,y), (u,x), and labels i at (v,x):
project x y u v w <data.cmplx |
	scat \
		-H "Second figure" \
		-X "Sample X axis" \
		-e  \
		-Y "NONrotated" \
		-Lw \
		-x 0,10,1 \
		-y 0,10,1 \
		-w 0,0.5,1,1

# NOTE: The -E option is used in the first example.
# This uses the extplotlib routines, which demand rotation and centering
# of text. Centering has been implemented in the enclosed xplot and hpglplot
# filters (essential for labels to make any sense). Rotation (of Y axis)
# has currently only been implemented in hpglplot, and makes much nicer plots.
\Rogue\Monster\
else
  echo "will not over write ./testgr/t4"
fi
if `test ! -s ./testgr/data.legend`
then
echo "writting ./testgr/data.legend"
cat > ./testgr/data.legend << '\Rogue\Monster\'
x	y	z	zlabel	ylegend	zlegend
-	-	-	------	-------	-------
1	2	4	x		
2	3	3			
3	1	3	xx		
4	1	4		y-label	z-label
\Rogue\Monster\
else
  echo "will not over write ./testgr/data.legend"
fi
if `test ! -s ./testgr/t5`
then
echo "writting ./testgr/t5"
cat > ./testgr/t5 << '\Rogue\Monster\'
   project x y z z zlabel y ylegend z zlegend < data.legend | 
	scat -E -x 0,10,1 -y 0,10,1 -L zlabel -L ylegend -L zlegend | 
	plot -Tx =500x500+1+1
\Rogue\Monster\
else
  echo "will not over write ./testgr/t5"
fi
if `test ! -s ./testgr/t6`
then
echo "writting ./testgr/t6"
cat > ./testgr/t6 << '\Rogue\Monster\'
   project x y z z zlabel y ylegend z zlegend < data.legend | 
	scat -E -x 0,10,1 -y 0,10,1 -L zlabel -L ylegend -L zlegend | 
	plot -Tx =500x500+1+1
\Rogue\Monster\
else
  echo "will not over write ./testgr/t6"
fi
if `test ! -s ./testgr/t3e`
then
echo "writting ./testgr/t3e"
cat > ./testgr/t3e << '\Rogue\Monster\'
#!/bin/sh
# 
# Slightly more complex plot. Data contains 3 columns.
# Plot contains col2(z) vs col1(y) as a line, with col4(w) as labels
# at the points (col1,col3) or (v,y)
# 
# This is what the data looks like:
#
# y	z	v	w
# -	-	-	-
# 1	2	3	*
# 2	3	4	**
# 3	4	5	***
# 4	5	6	v
# 5	6	7	vi
scat \
	-X "X-axis" \
	-Y "Y-axis" \
	-E \
	-x0,5,.5 \
	-y 0,10,1 \
	-L w \
	-H "Sample x/y-plot" \
	< data.3
#
# Note the use of -X and -Y to define axis labels.
# The Y-axis label is not rotated unless the -E option is added to
# the scat command-line. In this case, extended commands must be
# supported by the plot-filter used.
\Rogue\Monster\
else
  echo "will not over write ./testgr/t3e"
fi
echo "Finished archive 1 of 3"
exit

-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.