[comp.sources.unix] v20i005: Relational database and graphing tools, Part02/03

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

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

#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -d ./doc`
then
  mkdir ./doc
  echo "mkdir ./doc"
fi
if `test ! -s ./doc/math.1`
then
echo "writting ./doc/math.1"
cat > ./doc/math.1 << '\Rogue\Monster\'
.\" Man page for math(1)
.TH MATH 1 "1. April 1989"
.SH NAME
math - Simple mathematical summaries of a table
.SH SYNOPSIS
.B math
[
.I < data
]
.SH DESCRIPTION
.B Math
reads columnar data from the standard input and outputs a few
summary statistics.
.LP
This is best explained by way of an example. Suppose the file
.I data
contains the lines:
.nf
x       y       z       v
-       -       -       -
0       1       2       3
1               3       4
2       3       4       5
3       4       5       6
4       5       6       7
.fi
where exactly one tab-character separates the columns (note 
that the second y-value is missing - denoted by two adjacent 
tabs).
.LP
The command 
.I math < data
yields:
.nf
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
.fi
on the standard output.
.LP
The output should be self-explanatory.
.SH "SEE ALSO"
.BR reldb(1),\ compute(1).
.SH BUGS
.LP
.I Math 
assumes that two tabs in a row denotes a missing value.
This is usually a correct assumption - an empty columns is 
normally a missing
value and should not be counted or used in a sum.
.LP
.I Math
only does simple checks for the number of digits appropriate
for output. Sometimes this yields messy output, although most cases should 
be reasonable, as in the above example.
.LP
No checks for invalid data are made.
\Rogue\Monster\
else
  echo "will not over write ./doc/math.1"
fi
if `test ! -s ./doc/testdb.1`
then
echo "writting ./doc/testdb.1"
cat > ./doc/testdb.1 << '\Rogue\Monster\'
.\" Man page for testdb(1)
.TH TESTDB 1 "1. June 1989"
.SH NAME
testdb - test reldb programs
.SH SYNOPSIS
.B testdb
.SH DESCRIPTION
Testdb sets up a directory, testdb, as a subdirectory under the user's
home directory and runs some of the 
.I reldb
programs. 
.P
See the output files for more information.
.SH "SEE ALSO"
.BR reldb(1),\ testgr(1).
.SH BUGS
Not all programs are tested.
\Rogue\Monster\
else
  echo "will not over write ./doc/testdb.1"
fi
if `test ! -s ./doc/testgr.1`
then
echo "writting ./doc/testgr.1"
cat > ./doc/testgr.1 << '\Rogue\Monster\'
.\" Man page for testgr(1)
.TH TESTGR 1 "1. June 1989"
.SH NAME
testgr - test plot  programs in reldb package
.SH SYNOPSIS
.B testgr
.SH DESCRIPTION
Testdb sets up a directory, testgr, as a subdirectory under the user's
home directory and copies sample programs and datafiles into it.
.P
See the shell scripts, t1, t2 etc. for more information.
.SH "SEE ALSO"
.BR reldb(1),\ testdb(1).
.SH BUGS
No known bugs.
\Rogue\Monster\
else
  echo "will not over write ./doc/testgr.1"
fi
if `test ! -d ./misc`
then
  mkdir ./misc
  echo "mkdir ./misc"
fi
if `test ! -s ./misc/install`
then
echo "writting ./misc/install"
cat > ./misc/install << '\Rogue\Monster\'
\Rogue\Monster\
else
  echo "will not over write ./misc/install"
fi
if `test ! -s ./misc/Makefile`
then
echo "writting ./misc/Makefile"
cat > ./misc/Makefile << '\Rogue\Monster\'
BINDIR=../bin
CFLAGS= -DDEBUG=0
DESTFILES=$(BINDIR)/relprint $(BINDIR)/qscat

all:
	@echo "Use make install to install the scripts"

install: $(DESTFILES)
	touch install
$(BINDIR)/relprint : relprint.sh
	cp  relprint.sh $(BINDIR)/relprint
	chmod +x $(BINDIR)/relprint

$(BINDIR)/qscat : qscat.sh
	cp  qscat.sh $(BINDIR)/qscat
	chmod +x $(BINDIR)/qscat

\Rogue\Monster\
else
  echo "will not over write ./misc/Makefile"
fi
if `test ! -s ./misc/relprint.sh`
then
echo "writting ./misc/relprint.sh"
cat > ./misc/relprint.sh << '\Rogue\Monster\'
#!/bin/sh
# reldbprint -- prepares printing of reldb table using tbl.
#
# Usage: reldbprint title < reldb_table

trap "rm -f /tmp/tmp$$" 2 15

caption="$*"		# tablecaption

cat - > /tmp/tmp$$
read head < /tmp/tmp$$		# first get the header line

echo '.TS'		        # tell tbl this is a table

echo 'center doublebox;'	# and to draw a nice box around it
set - $head
captctrl=c			# Tbl header for caption
line1=c				# Handle header for first column
line3=l				# assume first col is label
shift
for i				# set up remaining tbl header lines of c's and n's
do
	captctrl=$captctrl"s"
	line1=$line1"c"		# Want to center column headers
	line3=$line3"n"		# Assume rest of cols are numbers
done
line3=$line3"."		# add the dot to end the tbl format
echo $captctrl

echo $line1		# output the tbl format 
echo $line3		# statements
echo .sp .3c
echo $caption		# then the table caption
echo .sp .3c
echo =			# double underline for caption
echo .sp .1c
echo "$head"		# next line of table data is the prelude header
echo .sp .1c
echo "_"		# underline the header in the table
sed 1,2d < /tmp/tmp$$	# now for the body of the table=data file
echo '.TE'		# and end the pretty little thing

rm -f /tmp/tmp$$
\Rogue\Monster\
else
  echo "will not over write ./misc/relprint.sh"
fi
if `test ! -s ./misc/qscat.sh`
then
echo "writting ./misc/qscat.sh"
cat > ./misc/qscat.sh << '\Rogue\Monster\'
#!/bin/sh
#
# qscat : a quick-and-dirty shell script for turning
#         Reldb files into files which can be run through grap(1)
#         to produce reasonable plots.
#         (I didn't say production-quality, but these are certainly a good
#         start - just edit the output)
echo '
\!! rasterize=300
.DF
.ce
\fB'$*'\fR
.G1
frame ht 2 wid 5
'
awk '
NR==1{for(i=1;i<=NF;i++){
	name[i]=$(i)
	}
	print "label bot ","\"",name[1],"\""
      }
NR==3{for(i=1;i<=NF;i++){
		prev[i]=$(i)
		if(i>1)print "\""name[i]"\" ljust at "$1","$(i)
		if(i==2)print "bullet at "$1","$(i)
		if(i==3)print "circle at "$1","$(i)
		if(i==4)print "plus at "$1","$(i)
		if(i==5)print "delta at "$1","$(i)
		if(i==6)print "box at "$1","$(i)
		if(i==7)print "star at "$1","$(i)
		if(i>=8)print "plus at "$1","$(i)
	  }
          }
	NR>3{for(i=2;i<=NF;i++){
		if(i==2){
			print "line from "prev[1]","prev[i]" to "$1","$(i)
			print "bullet at "$1","$(i)
		}
		if(i==3){
			print "line dashed from "prev[1]","prev[i]" to "$1","$(i)
			print "circle at "$1","$(i)
		}
		if(i==4){
			print "line dotted from "prev[1]","prev[i]" to "$1","$(i)
			print "plus at "$1","$(i)
		}
		if(i==5){
			print "delta at "$1","$(i)
			print "line dashed 0.1i from "prev[1]","prev[i]" to "$1","$(i)
		}
		if(i==6){
			print "box at "$1","$(i)
			print "line from "prev[1]","prev[i]" to "$1","$(i)
		}
		if(i==7){
			print "star at "$1","$(i)
			print "line from "prev[1]","prev[i]" to "$1","$(i)
		}
		if(i>=8){
			print "plus at "$1","$(i)
			print "line from "prev[1]","prev[i]" to "$1","$(i)
		}
		prev[i]=$(i)
	     }
	     prev[1]=$1
	   }'

echo '.G2
.DE'
\Rogue\Monster\
else
  echo "will not over write ./misc/qscat.sh"
fi
if `test ! -d ./plot1.src`
then
  mkdir ./plot1.src
  echo "mkdir ./plot1.src"
fi
if `test ! -s ./plot1.src/Makefile`
then
echo "writting ./plot1.src/Makefile"
cat > ./plot1.src/Makefile << '\Rogue\Monster\'
INCLUDES=/usr/local/include
CFLAGS=-I$(INCLUDES)
OBJ=plotfilter.o xplot.o hpglplot.o graplot.o
BINDIR=../bin

all: xplot hpglplot graplot plot.sh

xplot : $(OBJ)
	cc $(XCCFLAGS) -o xplot plotfilter.o xplot.o -lXaw -lXt -lX11 -lm
hpglplot : $(OBJ)
	cc -o hpglplot plotfilter.o hpglplot.o -lm
graplot: graplot.o plotfilter.o
	cc -o graplot graplot.o plotfilter.o
install: xplot graplot hpglplot plot.sh testgr.sh
	cp xplot graplot hpglplot $(BINDIR)
	cp plot.sh $(BINDIR)/plot
	chmod +x $(BINDIR)/plot
	cp testgr.sh $(BINDIR)/testgr
	chmod +x $(BINDIR)/testgr
	cp graplot $(BINDIR)
	touch install

clean: 
	rm -f $(OBJ) xplot hpglplot graplot
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/Makefile"
fi
if `test ! -s ./plot1.src/README`
then
echo "writting ./plot1.src/README"
cat > ./plot1.src/README << '\Rogue\Monster\'
This directory contains  :
	xplot, a plot(1) filter for X11.
	hpglplot, a plot(1) filter for hpgl.
	graplot, a plot(1) filter for grap output.

Xplot is derived from sunplot which arrived on the net a while ago. This
program will open an X window for the plot output. After running make,
try 
	scat -E -Lw < data | xplot =300x300+100+100

It seems impossible to do some of the things required for simple plots,
if using plot(5) only. Things like rotation and centering of labels are
essential. Hence we have enhanced the commands a bit, and the
enhancements are used by scat only if a special option is used. The
enclosed plot-filters support these extensions.

The hpgl-filter is a modified version of an hpgl-filter which arrived on
the net. The modifications are simply to allow for rotation and
centering. These modifications are the only reasons for reposting.

Graplot will take plot(5)-data and write output for the grap-program.
This is extremely handy for putting into a troff-style paper.

I (gunnar@hafro) apologize for not having gotten formal permission from
previous authors (notable Jim Constantine and Scott Sutherland)
to publish this modification of their code.
Their code was published on the net, however, and no E-mail 
addresses remained in the files when I obtained them.

WARNING: There is a bug in xplot. For some strange reason, the window
manager awm will crash when xplot is started without any coordinate
options. This is easily solved by always using some coordinates,
e.g. scat < data | plot -Tx =300x300+100+100 -- or as in the above example.
If anyone finds the problem, please let me know. The problem does not
seem to appear with uwm.
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/README"
fi
if `test ! -s ./plot1.src/hpglplot.c`
then
echo "writting ./plot1.src/hpglplot.c"
cat > ./plot1.src/hpglplot.c << '\Rogue\Monster\'

#include <sgtty.h>
#include <stdio.h>
#include <math.h>

/* HP-GL plot(5) library				*/
/* - does NOT do line locking				*/
/* - aspect ratio is not maintained			*/
/* Jim Constantine	               	 		*/
/* Copyright 1985 Sun Microsystems Inc.			*/
/* Extensions by asta@hafro.is (March, 1989) 		*/
/* Prepared for redistribution by gunnar@hafro.is	*/
/* Notable features, which are really bugs: This 
   program assumes it is writing to a device. That 
   causes problems when writing to e.g. hpgl2ps filters.
   Use of some special HPGL escape sequences may also cause
   problems						*/

openpl()
{
    struct sgttyb   sgarg;
    int local;

    ioctl( fileno(stdout), TIOCGETP, &sgarg);
    ioctl( fileno(stdout), TIOCLGET, &local);
    sgarg.sg_ispeed = sgarg.sg_ospeed = B9600;
    sgarg.sg_erase = sgarg.sg_kill = '#';
    sgarg.sg_flags = EVENP | ODDP;
    local = LDECCTQ;
    ioctl( fileno(stdout), TIOCSETP, &sgarg);
    ioctl( fileno(stdout), TIOCLSET, &local);

    /*printf("IN;\033.P1:");		/* out - gs */
    printf("IN;");
    fflush(stdout);

    printf("PG;AP 3;CA 10;CC 20;SR 0.6,1.2;SP 1;\n");
    fflush(stdout);
}

move(x, y)
{
    printf("PU %d,%d;\n", x, y);
}

line(x1, y1, x2, y2)
{
    printf("PU %d,%d PD %d,%d;\n", x1, y1, x2, y2);
}

label(s)
    char   *s;
{
    printf("LB%s\03;\n", s);
}

erase()
{
    printf("PG;AF;\n");		/* feed page if paper has been writen on */
}

point(x, y)
{
    printf("PU %d,%d PD PU;\n", x, y);
}

cont(x, y)
{
    printf("PD %d,%d;\n", x, y);
}

space(x1, y1, x2, y2)
{
    printf("SC %d,%d %d,%d;\n", x1, x2, y1, y2);
}

arc(xc, yc, x1, y1, x2, y2)
{
    /* args are:  center, start, end */
    float angle;

    angle = atan((float) (y2 - y1) / (float) (x2 - x1)) * 5.729578e+01;
    if ((x2 - x1) < 0) angle = 180.0 + angle;
    move(x2,y2);
    printf("AA %d,%d;%6.3f\n", x1, y1, angle);
}

circle(x, y, r)
{
    move(x,y);
    printf("CI %d;\n",r);
}

linemod(s)			/* line style */
    char *s;
{
    switch(s[3]) {

    case 't': /* dotTed */
	printf("LT 1;\n");
	break;

    case 'i': /* solId */
    default:
	printf("LT ;\n");
	break;
 
    case 'g': /* lonGdashed */
	printf("LT 3;\n");
	break;

    case 'r': /* shoRtdashed */
	printf("LT 2;\n");
	break;

    case 'd': /* dotDashed */
	printf("LT 4;\n");
	break;
    }
}

labelrotation(s)
    char *s;
{

    switch(s[1]) {

    case 'h': /* horizontal */
	printf("DI 1,0;\n");
	break;

    case 'v': /* vertical */
	printf("DI 0,1;\n");
	break;
    } 
}


labelplace(s)
    char *s;
{

    switch(s[1]) {

    case 'u': /* center the label under the point */
	printf("LO16;\n");
	break;

    case 'o': /* center the label over the point */
	printf("LO14;\n");
	break;

    case 'l': /* center the label left at the point */
	printf("LO18;\n");
	break;

    case 'r': /* center the label right at the point */
	printf("LO12;\n");
	break;

    case 'c': /* center the label at the point */
	printf("LO15;\n");
	break;

    default: /* center the label at the point */
	printf("LO15;\n");
	break;
    } 
}

selectcolor(s)
    char *s;
{

    switch(s[1]) {

    case '1': /* select pen 1 */
	printf("SP 1;\n");
	break;

    case '2': /* select pen 2 */
	printf("SP 2;\n");
	break;

    case '3': /* select pen 3 */
	printf("SP 3;\n");
	break;

    case '4': /* select pen 4 */
	printf("SP 4;\n");
	break;

    case '5': /* select pen 5 */
	printf("SP 5;\n");
	break;

    case '6': /* select pen 6 */
	printf("SP 6;\n");
	break;

    case '7': /* select pen 7 */
	printf("SP 7;\n");
	break;

    case '8': /* select pen 8 */
	printf("SP 8;\n");
	break;

    default: /* select pen 1 */
	printf("SP 1;\n");
	break;
    } 
}

closepl()
{
    printf ("SP;NR;PG;\n");
}

\Rogue\Monster\
else
  echo "will not over write ./plot1.src/hpglplot.c"
fi
if `test ! -s ./plot1.src/plotfilter.c`
then
echo "writting ./plot1.src/plotfilter.c"
cat > ./plot1.src/plotfilter.c << '\Rogue\Monster\'

#include <stdio.h>

static char buf[256];
int	argc_copy;
char	**argv_copy;

main(argc, argv)
    int  argc;
    char **argv;
{
    int x1,y1,x2,y2,x3,y3;
    int r;
    char c;

    argc_copy = argc;
    argv_copy = argv;

    openpl();

    while ((c = getc(stdin)) != EOF) {

	switch (c) {
	    case 'm': 			/* move */
		x1 = getint();
		y1 = getint();
		move(x1,y1);
		break;

 	    case 'n':			/* cont */
                x1 = getint();
                y1 = getint();
		cont(x1,y1); 
		break;
                	    
	    case 'p':			/* point */
		x1 = getint();
		y1 = getint();
		point(x1,y1);
		break;

	    case 'l': 			/* line */
		x1 = getint();
		y1 = getint();
		x2 = getint();
		y2 = getint();
		line(x1,y1,x2,y2);
		break;

	    case 't': 			/* text */
		string(buf);
		label(buf);
		break;

	    case 'e': 			/* erase */
		erase();
		break;

	    case 's': 			/* space */
		x1 = getint();
		y1 = getint();
		x2 = getint();
		y2 = getint();
		space(x1,y1,x2,y2);
		break;

	    case 'a': 			/* arc */
		x1 = getint();
		y1 = getint();
		x2 = getint();
		y2 = getint();
		x3 = getint();
		y3 = getint();
		arc(x1,y1,x2,y3,x3,y3);
		break;

	    case 'c': 			/* circle */
		x1 = getint();
		y1 = getint();
		r  = getint();
		circle(x1,y1,r);
		break;

	    case 'f': 			/* linemod */
		string(buf);
		linemod(buf);
		break;

	    case 'r': 			/* homemade labelrotation*/
		string(buf);
		labelrotation(buf);
		break;

	    case 'u': 			/* homemade labelplace*/
		string(buf);
		labelplace(buf);
		break;

	    case 'z': 			/* homemade colorfunction*/
		string(buf);
		selectcolor(buf);
		break;

	    default: 
		fprintf(stderr, "%s: unknown command 0x%x", argv[0], c & 0xff);
		if (c >= ' ')
		      fprintf(stderr, " '%c'\n", c);
		  else
		      fprintf(stderr, " '^%c'\n", c + '@');
	}
    }
    closepl();
}

getint()
{	
    /* get an integer stored in 2 ascii bytes. */
    short   b1,
            b2;
    if ((b1 = getchar()) == EOF)
	return (EOF);

    if ((b2 = getchar()) == EOF)
	return (EOF);

    b2 = b2 << 8;
    return (b2 | b1);
}

string(s)
    char *s;
{
    for (; *s = getchar(); s++) {
	if (*s == '\n')
	    break;
	}
    *s = '\0';
    return;
}
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/plotfilter.c"
fi
if `test ! -s ./plot1.src/xplot.c`
then
echo "writting ./plot1.src/xplot.c"
cat > ./plot1.src/xplot.c << '\Rogue\Monster\'
/************************************************************************
 *   Plot(5) interface library for XWindows				*
 *									*
 *   Asta G. March 1989                                                 *
 *   Adapted from a code for suntools by:                               *
 *									*
 *   	Scott Sutherland, November 1987					*
 *   	Boston University Math Department			       	*
 *									*
 *   This was adapted from a code by:					*
 *   	Jim Constantine, Janurary 1986					*
 *   which was in turn based on work by:				*
 *   	Mike Caplinger, Rice University, September 1984.		*
 ***********************************************************************/

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <strings.h>

#define FONT    "6x13.snf"
#define ARG_FONT                "font"


/* plot stuff */
float 		xscale = 1.0, yscale = 1.0;
float 		xorig = 0.0, yorig = 0.0;
int 		x, y;
int		use_labelplace=0;  /* 0=false, 1=true */
char		*label_pl;
int		xheight, yheight, width;
int winX, winY, winW, winH;

/* xwindow stuff */
XWMHints        xwmh = {
    (InputHint|StateHint),      /* flags */
    False,                       /* no input from keyboard */
    NormalState,                /* initial_state */
    0,                          /* icon pixmap */
    0,                          /* icon window */
    0, 0,                       /* icon location */
    0,                          /* icon mask */
    0,                          /* Window group */
};

char *ProgramName;

void Usage ()
{
        fprintf (stderr, "usage:  %s [-options ...]\n\n", ProgramName);
        fprintf (stderr, "where options include:\n");
        fprintf (stderr, "    -geometry geom           size of window\n");
        fprintf (stderr, "\n");
        exit (1);
}

extern    int argc_copy;
extern    char **argv_copy;

char **ap;
char *geom = NULL;
Display    *dpy;            /* X server connection */
Screen *scr;
Window      win;            /* Window ID */
GC          gc;             /* GC to draw with */
char        *fontName;      /* Name of the font to use */
XFontStruct *fontstruct;    /* Font descriptor */
unsigned long fth, ftw, pad;     /* Font size parameters */
unsigned long fg, bg, bd;   /* Pixel values */
unsigned long bw;           /* Border width */
XGCValues   gcv;            /* Struct for creating GC */
XEvent      event;          /* Event received */
XSizeHints  xsh;            /* Size hints for window manager */
char       *geomSpec;       /* Window geometry string */
XSetWindowAttributes xswa;  /* Temporary Set Window Attribute struct
Window win;
 
/************************************************************************/
/*			openpl						*/
/************************************************************************/
openpl() {

 /* Process arguments: */
    ap = argv_copy;  
    while (*++ap) {
        if (!strncmp(*ap, "-g", 2)) {
                if (*++ap) {
                        geom = *ap;
                } else
                        Usage ();
        } else if (**ap == '=')
                        geom = *ap;
    }

  /*
     * Open the display using the $DISPLAY environment variable to locate
     * the X server.  See Section 2.1.
     */
    if ((dpy = XOpenDisplay(NULL)) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", argv_copy[0], XDisplayName(NULL));
        exit(1);
    }
     /* Select the font to use */
    if ((fontName = XGetDefault(dpy, argv_copy[0], ARG_FONT)) == NULL) {
        fontName = FONT;
    }
    if ((fontstruct = XLoadQueryFont(dpy, fontName)) == NULL) {
        fprintf(stderr, "%s: display %s doesn't know font %s\n",
                argv_copy[0], DisplayString(dpy), fontName);
        exit(1);
    }
    fth = fontstruct->max_bounds.ascent + fontstruct->max_bounds.descent;
/*    fth = fontstruct->ascent + fontstruct->descent; */
    ftw = fontstruct->max_bounds.width;

	    /*
     * Select colors for the border,  the window background,  and the
     * foreground.
     */
    bd = BlackPixel(dpy, DefaultScreen(dpy));
    bg = WhitePixel(dpy, DefaultScreen(dpy));
    fg = BlackPixel(dpy, DefaultScreen(dpy)); 

    /*
     * Set the border width of the window
     */
     bw = 3;

     /*
     * Create the Window with the information in the XSizeHints, the
     * border width,  and the border & background pixels. See Section 3.3.
     */
     scr = DefaultScreenOfDisplay(dpy);
     xsh.width = 500;
     xsh.height = 300;
     xsh.x = 0; 
     xsh.y = 0;
     xsh.flags = (PPosition | PSize); 
  
     if (geom) {
        XParseGeometry(geom, &xsh.x, &xsh.y, &xsh.width, &xsh.height);
	xsh.flags = (USPosition | USSize);
     }
        
     win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy),
                      xsh.x, xsh.y, xsh.width, xsh.height,
                      bw, bd, bg);
      
     /* 
     * Set the standard properties for the window managers. See Section
     * 9.1.
     */
    XSetStandardProperties(dpy, win, "", "", None, argv_copy, argc_copy,&xsh);
    XSetWMHints(dpy, win, &xwmh);

        scr = DefaultScreenOfDisplay(dpy);
                

     /*
     * Ensure that the window's colormap field points to the default
     * colormap,  so that the window manager knows the correct colormap to
     * use for the window.  See Section 3.2.9. Also,  set the window's Bit
     * Gravity to reduce Expose events.
     */
     xswa.save_under=True;
     xswa.backing_store = Always;
     xswa.colormap = DefaultColormap(dpy, DefaultScreen(dpy));
     xswa.bit_gravity = CenterGravity;
     XChangeWindowAttributes(dpy, win, (CWSaveUnder | CWBackingStore | CWColormap | CWBitGravity),&xswa);

     /*
     * Create the GC for plotting.  See Section 5.3.
     */

     gcv.font = fontstruct->fid;
     gcv.foreground = fg;
     gcv.background = bg;
/*     gcv.function=GXand;
     gcv.plane_mask=BlackPixel(dpy,DefaultScreen(dpy)) ^
                    WhitePixel(dpy,DefaultScreen(dpy));    */
     gc = XCreateGC(dpy, win, (GCFont | GCForeground | GCBackground ), &gcv);

    /*
     * Specify the event types we're interested in - only Exposures. See
     * Sections 8.5 & 8.4.5.1
     */
    XSelectInput(dpy, win, ExposureMask);
     
    /*
     * Map the window to make it visible.  See Section 3.5.
     */
    XMapWindow(dpy, win);     
    XNextEvent(dpy, &event);
   
}
/************************************************************************/
/*			move						*/
/************************************************************************/
move(x1, y1) {
    x = scalex(x1);
    y = scaley(y1);
}
/************************************************************************/
/*			cont						*/
/************************************************************************/
cont(x1, y1) {
    x1 = scalex(x1);
    y1 = scaley(y1);
    XDrawLine(dpy, win, gc, x, y, x1, y1);
    x = x1;
    y = y1;
    XFlush(dpy);
}
/************************************************************************/
/*			point						*/
/************************************************************************/
point(x, y) {
    x = scalex(x);
    y = scaley(y);
    XDrawRectangle(dpy, win, gc, x, y, 1, 1);
    XFlush(dpy);
}
/************************************************************************/
/*			line						*/
/************************************************************************/
line(x1, y1, x2, y2) {
    x1 = scalex(x1);
    y1 = scaley(y1);
    x2 = scalex(x2);
    y2 = scaley(y2);
    XDrawLine(dpy, win, gc, x1, y1, x2, y2);
    XFlush(dpy);
}
/************************************************************************/
/*			circle						*/
/*		Not implemented						*/
/************************************************************************/
circle(x1, y1, r) {
      x1=scalex(x1-r);
      y1=scaley(y1-r);
      width=scalex(2*r);
      XDrawArc(dpy,win,gc,x1,y1,width,width,0,23040);
      XFlush(dpy);
}
/************************************************************************/
/*			arc						*/
/*		Not implemented						*/
/************************************************************************/
arc(cx, cy, sx, sy, ex, ey) 
{
}
/************************************************************************/
/*			label						*/
/************************************************************************/
label(s)
char *s;
{
    if(!use_labelplace){
          XDrawString(dpy, win, gc, x, y, s, strlen(s));
          XFlush(dpy);
          }
    else {
        switch(*label_pl){
		case 'u':
                      x=x-XTextWidth(fontstruct,s,strlen(s))/2;
                      y=y+fth;
                      XDrawString(dpy, win, gc, x, y, s, strlen(s));
                      XFlush(dpy);
                      break;

		case 'o': /* center the label over the point */
                      x=x-XTextWidth(fontstruct,s,strlen(s))/2;
                      XDrawString(dpy, win, gc, x, y, s, strlen(s));
                      XFlush(dpy);
                      break;
        
		case 'l': /* center the label left at the point */
                      x=x-XTextWidth(fontstruct,s,strlen(s));
/*		      y=y-fth/2+fontstruct->ascent; */
		      y=y-fth/2+fontstruct->max_bounds.ascent;
                      XDrawString(dpy, win, gc, x, y, s, strlen(s));
                      XFlush(dpy);
                      break;
        
	        case 'r': /* center the label right at the point */
/*		      y=y+fth/2;  */
		      y=y-fth/2+fontstruct->max_bounds.ascent;
                      XDrawString(dpy, win, gc, x, y, s, strlen(s));
                      XFlush(dpy);
	              break;
    
	        case 'c': /* center the label at the point */
                      x=x-XTextWidth(fontstruct,s,strlen(s))/2;
		      y=y-fth/2+fontstruct->max_bounds.ascent;
/*		      y=y+fth/2;  */
                      XDrawString(dpy, win, gc, x, y, s, strlen(s));
                      XFlush(dpy);
	              break;
	
	        default: /* center the label at the point */
                      x=x-XTextWidth(fontstruct,s,strlen(s))/2;
		      y=y-fth/2+fontstruct->max_bounds.ascent;
/*		      y=y+fth/2;   */
	              XDrawString(dpy, win, gc, x, y, s, strlen(s));
        	      XFlush(dpy);
	              break;
	  }
     }
}
/************************************************************************/
/*			labelplace -- a homemade function						*/
/************************************************************************/
labelplace(s)
    char *s;
{
     
    switch(s[1]) {

    case 'u': /* center the label under the point */
        use_labelplace=1;
        label_pl="u";
        break;
    
    case 'o': /* center the label over the point */
        use_labelplace=1;
        label_pl="o";
        break;
        
    case 'l': /* center the label left at the point */
        use_labelplace=1;
        label_pl="l";
        break;
        
    case 'r': /* center the label right at the point */
        use_labelplace=1;
        label_pl="r";
        break;
    
    case 'c': /* center the label at the point */
        use_labelplace=1;
        label_pl="c";
        break;

    default: /* center the label at the point */
        use_labelplace=1;
        label_pl="c";
        break;
    }
}

/************************************************************************/
/*			labelrotation  - a homemade function            */
/*			not implemented  				*/
/************************************************************************/
labelrotation(s)
    char *s;
{
        
    switch(s[1]) {

    case 'h': /* horizontal */
        break;
 
    case 'v': /* vertical */
        break;
    }
}

/************************************************************************/
/*	  		selectcolor  - a homemade function              */
/*			not implemented  				*/
/************************************************************************/
selectcolor(s)
    char *s;
{
    
    switch(s[1]) {
        
    case '1': /* select pen 1 */
        break;
        
    case '2': /* select pen 2 */
        break;
        
    case '3': /* select pen 3 */
        break;
 
    case '4': /* select pen 4 */
        break;
 
    case '5': /* select pen 5 */
        break;

    case '6': /* select pen 6 */
        break;
    
    case '7': /* select pen 7 */
        break;
    
    case '8': /* select pen 8 */
        break;

    default: /* select pen 1 */
        break;
    }
}    

/************************************************************************/
/*			erase						*/
/************************************************************************/
erase() {
    XClearWindow(dpy, win);
    XFlush(dpy);
}

/************************************************************************/
/*			linemod						*/
/*		    Not implemented					*/
/************************************************************************/
linemod(s)
char *s;
{

    switch(s[3]) {
    case 't': /* dotTed */
        break;

    case 'i': /* solId */
    default:
        break;

    case 'g': /* lonGdashed */
        break;

    case 'r': /* shoRtdashed */
        break;

    case 'd': /* dotDashed */
        break;

    }
}
/************************************************************************/
/*			space						*/
/************************************************************************/
space(xorigi, yorigi, x1, y1) {
    xorig = xorigi;
    yorig = yorigi;
    xscale = ((float) xsh.width) / (x1 - xorig);
    yscale = ((float) xsh.height) / (y1 - yorig);
}

/************************************************************************/
/*			closepl						*/
/************************************************************************/
closepl() {
  XFlush(dpy);
  sleep(100000);
  return;
}

/************************************************************************/
/*			scalex						*/
/************************************************************************/
static scalex(xi) {
    float x;

    x = xi;
    x -= xorig;
    x = x * xscale;
    return((int) x);
}
/************************************************************************/
/*			scaley						*/
/************************************************************************/
static scaley(yi) {
    float y;

    y = yi;
    y -= yorig;
    y = y * yscale;
    y = xsh.height - y; /* origin at lower left. */
    return((int) y);
}

\Rogue\Monster\
else
  echo "will not over write ./plot1.src/xplot.c"
fi
if `test ! -s ./plot1.src/plot.sh`
then
echo "writting ./plot1.src/plot.sh"
cat > ./plot1.src/plot.sh << '\Rogue\Monster\'
#!/bin/sh
#
# plot -- plot filter; controls execution of filter for
#                      appropriate device.
#
# DOES NOT CONTAIN AT&T CODE.
#
# There are currently available PD filters for at least HPGL, X11
# and Postscript. The first two are included in the reldb distribution,
# as the xplot program is new and the hpglplot program has been extended
# somewhat to accept a few extended plot(5)-commands.
#
# These three filters would seem to suffice for a very large number
# of applications. Development of general utilities which use the
# plot(5) output format would therefore seem to be of potentially 
# great use.
#
#
case $1 in
-T*)	devarg=$1
	shift ;;
*)	echo "Usage: plot -Tfilter [otherargs]"
	exit 1 ;;
esac
case $devarg in
-Thpgl)		hpglplot $* ;;
-TX*|-Tx*)	xplot $* ;;
-Tps*)		psplot $* ;;
-Tgrap*)	graplot $* ;;
esac
exit 0
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/plot.sh"
fi
if `test ! -s ./plot1.src/graplot.c`
then
echo "writting ./plot1.src/graplot.c"
cat > ./plot1.src/graplot.c << '\Rogue\Monster\'
#include <sgtty.h>
#include <stdio.h>
#include <math.h>

/* HP-GL plot(5) library				*/
/* - does NOT do line locking				*/
/* - aspect ratio is not maintained			*/
/* Jim Constantine	               	 		*/
/* Copyright 1985 Sun Microsystems Inc.			*/
/* Extensions by ingi@hafro.is (June, 1989) 		*/
/* Prepared for redistribution by gunnar@hafro.is	*/
/* Notable features: This program is to be used to
   create troff files.  It can be used to print to a 
   device without putting the statements through a file.
   just use scat < file | graplot | lprenta8		*/

static char stre[15];
static char just[10];
static char jus1[10];
static char tex1[10];
openpl()
{
    struct sgttyb   sgarg;
    int local;
    printf("\\!! rasterize=300\n");
    printf(".G1\n");

    printf("frame invis ht 4 wid 6.2\n");
    printf("X=1\nY=0\n");
    printf("draw solid\n");
}
move(X, Y)
{
    /* printf("move from X,Y to %d,%d\n",X,Y);*/
    printf("X=%d\n",X);
    printf("Y=%d\n",Y);
}

line(X1, Y1, X2, Y2)
{
    printf("line %s from %d,%d to %d,%d\n", stre,X1, Y1, X2, Y2);
}

label(s)
    char   *s;
{
    printf("\"%s\" %s at X%s,Y%s\n",s,tex1,just,jus1);
}

erase()
{
    printf("\n");		/* feed page if paper has been writen on */
}

point(X, Y)
{
    printf("line %s from %d,%d to %d,%d\n",stre, X,Y,X, Y);
}

cont(X, Y)
{
    printf("line %s from X,Y to %d,%d\n", stre,X, Y);
    printf("X=%d\n",X);
    printf("Y=%d\n",Y);
}

space(X1, Y1, X2, Y2)
{
    printf("ticks bot out .0001i from %d to %d by %d \"\"\n",X1,X2,X2);
    printf("ticks left out .0001i from %d to %d by %d \"\"\n",X1,X2,X2);
}

arc(Xc, Yc, X1, Y1, X2, Y2)
{
    /* args are:  center, start, end */
 }

circle(X, Y, r)
{
}

linemod(s)			/* line stYle */
    char *s;
{
    switch(s[3]) {

    case 't': /* dotTed */
	printf("new dotted\n");
	strcpy(stre,"dotted");
	break;

    case 'i': /* solId */
    default:
	printf("new solid\n");
	strcpy(stre,"solid");
	break;
 
    case 'g': /* lonGdashed */
	printf("new dashed\n");
	strcpy(stre,"dashed");
	break;

    case 'r': /* shoRtdashed */
	printf("new dashed .5i\n");
	strcpy(stre,"dashed .1i");
	break;

    case 'd': /* dotDashed */
	printf("new dashed .05i\n");
	strcpy(stre,"dashed .05i");
	break;
    }
}

labelrotation(s)
    char *s;
{

 /*   switch(s[1]) {

    case 'h': 
	printf("DI 1,0\n");
	

    case 'v': 
	printf("DI 0,1\n");
	
    } 
*/}


labelplace(s)
    char *s;
{

    switch(s[1]) {

    case 'u': /* center the label under the point */
	strcpy(just,"-0");
	strcpy(jus1,"-0");
        strcpy(tex1,"below");
	break;

    case 'o': /* center the label over the point */
	strcpy(just,"-0");
	strcpy(jus1,"+0");
        strcpy(tex1,"above");
	break;

    case 'l': /* center the label left at the point */
	strcpy(jus1,"-0");
	strcpy(just,"-0");
	strcpy(tex1,"rjust");
	break;

    case 'r': /* center the label right at the point */
	strcpy(jus1,"-0");
	strcpy(just,"+0");
	strcpy(tex1,"ljust");
	break;

    case 'c': /* center the label at the point */
	strcpy(just,"-0");
	strcpy(jus1,"-0");
        strcpy(tex1,"");
	break;

    default: /* center the label at the point */
	strcpy(just,"-0");
	strcpy(jus1,"-0");
        strcpy(tex1,"");
	break;
    } 
}

selectcolor(s)
    char *s;
{

    /* switch(s[1]) {

    case '1': /* select pen 1 
	printf("SP 1\n");
	break;

    case '2': /* select pen 2 
	printf("SP 2\n");
	break;

    case '3': /* select pen 3 
	printf("SP 3\n");
	break;

    case '4': /* select pen 4 
	printf("SP 4\n");
	break;

    case '5': /* select pen 5 
	printf("SP 5\n");
	break;

    case '6': /* select pen 6 
	printf("SP 6\n");
	break;

    case '7': /* select pen 7 
	printf("SP 7\n");
	break;

    case '8': /* select pen 8 
	printf("SP 8\n");
	break;

    default: /* select pen 1 
	printf("SP 1\n");
	break;
    } */ 
}

closepl()
{
    printf (".G2\n");
}









\Rogue\Monster\
else
  echo "will not over write ./plot1.src/graplot.c"
fi
if `test ! -d ./plot1.src/Junk`
then
  mkdir ./plot1.src/Junk
  echo "mkdir ./plot1.src/Junk"
fi
if `test ! -s ./plot1.src/Junk/graplot.c`
then
echo "writting ./plot1.src/Junk/graplot.c"
cat > ./plot1.src/Junk/graplot.c << '\Rogue\Monster\'
#include <sgtty.h>
#include <stdio.h>
#include <math.h>

/* HP-GL plot(5) library				*/
/* - does NOT do line locking				*/
/* - aspect ratio is not maintained			*/
/* Jim Constantine	               	 		*/
/* Copyright 1985 Sun Microsystems Inc.			*/
/* Extensions by ingi@hafro.is (June, 1989) 		*/
/* Prepared for redistribution by gunnar@hafro.is	*/
/* Notable features: This program is to be used to
   create troff files.  It can be used to print to a 
   device without putting the statements through a file.
   just use scat < file | graplot | lprenta8		*/

static char stre[15];
static char just[10];
static char jus1[10];
static char tex1[10];
openpl()
{
    struct sgttyb   sgarg;
    int local;
    printf("\\!! rasterize=300\n");
    printf(".G1\n");

    printf("frame invis ht 4 wid 6.2\n");
    printf("X=1\nY=0\n");
    printf("draw solid\n");
}
move(X, Y)
{
    /* printf("move from X,Y to %d,%d\n",X,Y);*/
    printf("X=%d\n",X);
    printf("Y=%d\n",Y);
}

line(X1, Y1, X2, Y2)
{
    printf("line %s from %d,%d to %d,%d\n", stre,X1, Y1, X2, Y2);
}

label(s)
    char   *s;
{
    printf("\"%s\" %s at X%s,Y%s\n",s,tex1,just,jus1);
}

erase()
{
    printf("\n");		/* feed page if paper has been writen on */
}

point(X, Y)
{
    printf("line %s from %d,%d to %d,%d\n",stre, X,Y,X, Y);
}

cont(X, Y)
{
    printf("line %s from X,Y to %d,%d\n", stre,X, Y);
    printf("X=%d\n",X);
    printf("Y=%d\n",Y);
}

space(X1, Y1, X2, Y2)
{
    printf("ticks bot out .0001i from %d to %d by %d \"\"\n",X1,X2,X2);
    printf("ticks left out .0001i from %d to %d by %d \"\"\n",X1,X2,X2);
}

arc(Xc, Yc, X1, Y1, X2, Y2)
{
    /* args are:  center, start, end */
 }

circle(X, Y, r)
{
}

linemod(s)			/* line stYle */
    char *s;
{
    switch(s[3]) {

    case 't': /* dotTed */
	printf("new dotted\n");
	strcpy(stre,"dotted");
	break;

    case 'i': /* solId */
    default:
	printf("new solid\n");
	strcpy(stre,"solid");
	break;
 
    case 'g': /* lonGdashed */
	printf("new dashed\n");
	strcpy(stre,"dashed");
	break;

    case 'r': /* shoRtdashed */
	printf("new dashed .5i\n");
	strcpy(stre,"dashed .1i");
	break;

    case 'd': /* dotDashed */
	printf("new dashed .05i\n");
	strcpy(stre,"dashed .05i");
	break;
    }
}

labelrotation(s)
    char *s;
{

 /*   switch(s[1]) {

    case 'h': 
	printf("DI 1,0\n");
	

    case 'v': 
	printf("DI 0,1\n");
	
    } 
*/}


labelplace(s)
    char *s;
{

    switch(s[1]) {

    case 'u': /* center the label under the point */
	strcpy(just,"-0");
	strcpy(jus1,"-15");
        strcpy(tex1,"");
	break;

    case 'o': /* center the label over the point */
	strcpy(just,"-0");
	strcpy(jus1,"+15");
        strcpy(tex1,"");
	break;

    case 'l': /* center the label left at the point */
	strcpy(jus1,"-0");
	strcpy(just,"-0");
	strcpy(tex1,"rjust");
	break;

    case 'r': /* center the label right at the point */
	strcpy(jus1,"-0");
	strcpy(just,"+0");
	strcpy(tex1,"ljust");
	break;

    case 'c': /* center the label at the point */
	strcpy(just,"-0");
	strcpy(jus1,"-0");
        strcpy(tex1,"");
	break;

    default: /* center the label at the point */
	strcpy(just,"-0");
	strcpy(jus1,"-0");
        strcpy(tex1,"");
	break;
    } 
}

selectcolor(s)
    char *s;
{

    /* switch(s[1]) {

    case '1': /* select pen 1 
	printf("SP 1\n");
	break;

    case '2': /* select pen 2 
	printf("SP 2\n");
	break;

    case '3': /* select pen 3 
	printf("SP 3\n");
	break;

    case '4': /* select pen 4 
	printf("SP 4\n");
	break;

    case '5': /* select pen 5 
	printf("SP 5\n");
	break;

    case '6': /* select pen 6 
	printf("SP 6\n");
	break;

    case '7': /* select pen 7 
	printf("SP 7\n");
	break;

    case '8': /* select pen 8 
	printf("SP 8\n");
	break;

    default: /* select pen 1 
	printf("SP 1\n");
	break;
    } */ 
}

closepl()
{
    printf (".G2\n");
}









\Rogue\Monster\
else
  echo "will not over write ./plot1.src/Junk/graplot.c"
fi
if `test ! -s ./plot1.src/testgr.sh`
then
echo "writting ./plot1.src/testgr.sh"
cat > ./plot1.src/testgr.sh << '\Rogue\Monster\'
#!/bin/sh
#
# testgr -- user script for testing reldb programs.
#

PLOTDIR=/usr/local/src/Reldb/testgr

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

# Go home first - no need to clutter discs
cd
if [ ! -d testgr ]
then
	mkdir testgr
fi
cd testgr
PWD=`pwd`
echo "Copying programs and data into $PWD - hold on ..."
cp $PLOTDIR/* .
echo "Now run the sample programs, for example 't1 | xplot =500x500+300+300'"
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/testgr.sh"
fi
if `test ! -s ./plot1.src/install`
then
echo "writting ./plot1.src/install"
cat > ./plot1.src/install << '\Rogue\Monster\'
\Rogue\Monster\
else
  echo "will not over write ./plot1.src/install"
fi
if `test ! -d ./reldb.src`
then
  mkdir ./reldb.src
  echo "mkdir ./reldb.src"
fi
if `test ! -s ./reldb.src/addcol.sh`
then
echo "writting ./reldb.src/addcol.sh"
cat > ./reldb.src/addcol.sh << '\Rogue\Monster\'
#!/bin/sh
#
# addcol - add columns to a table
#
# Usage: addcol columns < data
#
# Author: gunnar@hafro.is
# Revisions: none yet ?
#
# NOTE: This seems to generate an invalid table -- extra tabs
#       should be added in the data part.

add=
for i 
do
	add=$add'	'$i
done
sed '1{
s/$/'"$add"'/
p
s/[^	]/-/g
}
2d' 
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/addcol.sh"
fi
if `test ! -s ./reldb.src/addup.c`
then
echo "writting ./reldb.src/addup.c"
cat > ./reldb.src/addup.c << '\Rogue\Monster\'
/*
	Procedure addup.

Usage: addup p < data

	Typical input line : a(1) a(2) ... a(p) b(1) ... b(nb)
	Output : For each level of (a(1),...,a(p)), print
		the sum  of all the b's.
	The a's are referred to as the 'by'-variables;
	The b's are the 'on'-variables.

Revision history:
	Original author : 
			gunnar@hafro.is (sometime in 86)
	All sorts of additions
		Mainly incorrect string manipulations
		also some dubious use of intermixed float and double -
		now all double.
			gunnar@hafro.is (April, 1989)
General comments:
	This program is rarely used directly by a human.
	Rather, it is a piece of the subtotal program,
	- subtotal call first project to order the by-variables
	first and then pipes the output into addup.
	This is what's called quick-and-dirty programming,
	but it's a heck of a lot simpler than having to
	build project into subtotal.
						*/


#include <stdio.h>
#include <strings.h>

#ifndef DEBUG
#define DEBUG 0		/* Define positive for debug (can override in Makefile*/
#endif

#define MAXV 25		/* maximum number of a-variables */
#define MAXLIN 150	/* maximum line length */

int debug=DEBUG;	/* debug level*/
int p;			/* numerical equiv. of arguments = number of by-vbls*/
int nonvar;		/* number of on-variables */
int i;			/* index */
double x[MAXV];		/* input b-vbls (i.e. one line at a time) */

main(argc,argv)
int argc;
char *argv[];
{
	char line[MAXLIN];	/* input line */
	char oldline[MAXLIN];	/* previous input line */
	int c;
	double sum[MAXV];	/* vector of sums for a b-val*/

        /* read argument = # vbls into p */
	if(debug)
		fprintf(stderr,"Into addup-routine\n");
	if(argc==2 ){
        	if(sscanf(argv[1], "%d", &p) != 1) {
			printf("usage: addup  p \n or: addup debuglevel p\n");
                	return(-1);
        	}
	} else if (argc==3){
        	if(sscanf(argv[1], "%d", &debug) != 1) {
			printf("usage: addup  p \n or: addup debuglevel p\n");
                	return(-1);
        	}
        	if(sscanf(argv[2], "%d", &p) != 1) {
			printf("usage: addup  p \n or: addup debuglevel p\n");
                	return(-1);
        	}
	} else {
		printf("usage: addup  p \n or: addup debuglevel p\n");
                return(-1);
	}
	if(debug>=2)
		fprintf(stderr,"Got argument:->%d<-\n",p);
	if(fgets(oldline,MAXLIN,stdin)==NULL){
		fprintf(stderr,"Cannot read first line of input\n");
		exit(1);
	}
	if(debug>=5)
		fprintf(stderr,"Got header:->%s<-\n",oldline);
	fputs(oldline,stdout);
	if(fgets(oldline,MAXLIN,stdin)==NULL){
		fprintf(stderr,"Cannot read second line of input\n");
		exit(1);
	}
	fputs(oldline,stdout);
	c=getline(oldline,p,x);
	nonvar=c;
	if(debug>=5){
		fprintf(stderr,"Got first dataline(on-part):->%s<-\n",oldline);
		fprintf(stderr,"\tGot sum-variable:->%d<-\n",x[0]);
		fprintf(stderr,"\t# on vars:%d\n",nonvar);
		}
	addup(sum);
	while(c!=EOF){
		c=getline(line,p,x);
		if(debug>=5){
			fprintf(stderr,"Got dataline(on-part):->%s<-\n",line);
			fprintf(stderr,"\tGot sum-variable:->%lf<-\n",x[0]);
			fprintf(stderr,"\t# on vars:%d\n",c);
		}
		if(	c!=EOF && 
			strlen(oldline)==strlen(line) && 
			!strcmp(oldline,line)	){

			if(debug>=5){
				fprintf(stderr,"Same by-columns-adding\n");
			}
			addup(sum);/* same a-vbls;add */
		}else{
			if(debug>=5){
				fprintf(stderr,"New by-cols-print old line(%s):\n",oldline);
			}
			output(oldline,sum);	/* output */
			if(debug>=5){
				fprintf(stderr,"\told line>%s< becomes >%s<",oldline,line);
			}
			(void)strcpy(oldline,line);	/* copy header */
			if(c!=EOF)
				addup(sum);/* new and final a's*/
		}
	}
        return(0);
}

getline(line,p,x)
char line[MAXLIN];	/* remainder of input line (the b's=by-columns)*/
int p;			/* no of vbls */
double x[MAXV];		/* columns to be summed */
{
	int i=0;
	int count=1;
	int	c;
	char	tmplin[MAXLIN];
	if((c=getchar())==EOF)
		return(EOF);
	do {
		line[i++]=c;
		while((c=getchar())!='\t')	/* get 'by' part as a string */
			line[i++]=c;
		count++;
	}while(count<=p);
	line[i]='\0';
	if(debug>=5)fprintf(stderr,"Input:by-vbls >%s<\n",line);
	count=0;
	do {
		i=0;
		c=getchar();
		while(c!='\t'&&c!='\n'){
			tmplin[i++]=c;
			c=getchar();
		}
		tmplin[i]='\0';
		if(debug>=5)fprintf(stderr,"\t next on-vbl >%s<\n",tmplin);
		if(i!=0){
			sscanf(tmplin,"%lf",&x[count]);	/* get 'on' variables */
			if(debug>=5)fprintf(stderr,"\t on-vbl:%lf\n",x[count]);
		} else {
			if(debug>=5)fprintf(stderr,"\t empty on-vbl\n");
			x[count]=0.;
		}
		count++;
	} while(c!='\n');
	return(count);

}	/* getline */

addup(sum)
double sum[MAXV];	/* vector of sums */
{
	static int first=1;
	if(debug>=2)
		fprintf(stderr,"Adding up:\n");
	if(first){
		if(debug>=5)
			fprintf(stderr,"\tinit\n");
		for(i=0;i<nonvar;i++){
			sum[i]=0.;		/* initialize*/
		first=0;
		}
	}
	for(i=0;i<nonvar;i++){
		if(debug>=5)
			fprintf(stderr,"\tAdding %lf to %lf\n",x[i],sum[i]);
		sum[i]+=x[i];		/* sum for vbl i */
	}
}	/* addup */
	
output(oldline,sum)
char oldline[MAXLIN];	/* previous input line, a-values (on) */
double sum[MAXV];	/* vector of sums (b's-on vbls) for a fixed a-val*/
{
	for(i=0;i<MAXLIN&&oldline[i]!='\0'&oldline[i]!='\n';i++)
		printf("%c",oldline[i]);	/* print text in beg. of line */
	for(i=0;i<nonvar;i++){			/* cut down digits output */
		if((double)(int)sum[i] == sum[i])
			printf("	%ld",(long)sum[i]);
		else if((double)(int)sum[i]<sum[i]-.00001||sum[i]<1.)
			printf("	%lf",sum[i]);
		else
			printf("	%ld",(long)sum[i]);
		sum[i]=0;
	}
	printf("\n");
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/addup.c"
fi
if `test ! -s ./reldb.src/invert.sh`
then
echo "writting ./reldb.src/invert.sh"
cat > ./reldb.src/invert.sh << '\Rogue\Monster\'
#!/bin/sh
#
# invert -- inverse of matrix command.
#
awk 'NR==1{for(i=1;i<=NF;i++)name[i]=$(i)}
NR==2{print name[1]"	col	data" ; print "----	---	----"}
NR>2{for(i=2;i<=NF;i++){OFS="	";print $1,name[i],$(i)}}'
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/invert.sh"
fi
if `test ! -s ./reldb.src/bplokk.sh`
then
echo "writting ./reldb.src/bplokk.sh"
cat > ./reldb.src/bplokk.sh << '\Rogue\Monster\'
#!/bin/sh
#
# Simple jointable -- first file must be sufficiently short so that
# a grep command can be set up from the whole file
GREP=`awk '
BEGIN {printf("egrep ")}
NR==3{FS="	";printf("^%s",$1)}
NR>3{FS="	";printf("|^%s",$1)}
END{print ""}'  < $1 `

# uncomment the following if you want to see what is going on
#echo $GREP

head -2 < $2
$GREP < $2
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/bplokk.sh"
fi
if `test ! -s ./reldb.src/check.sh`
then
echo "writting ./reldb.src/check.sh"
cat > ./reldb.src/check.sh << '\Rogue\Monster\'
#!/bin/sh
#
# check - checks sanity of reldb tables.
#
# The initial sed-command simply places dots in between two
# adjacent tabs, to guarantee that they are regarded as two
# fields by awk.
for i 
do
	sed 's/		/	.	/g
	s/		/	.	/g' < $i |\
	awk 'BEGIN {FS="	"}
	NR==1{
		reclen=NF
		error=0}
	NR==2{
		if(NF!=reclen){
			print "Dashes do not match column heads"
			error=1
		}
	}
	NR>2 {
		if(NF!=reclen){
			print "Error in line number ",NR,"fields ",NF," headers ",reclen;error=1
		}
	}
	END {
		if(error==0)
		print "Table '$i' is ok"
	}'
done
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/check.sh"
fi
if `test ! -s ./reldb.src/compute.c`
then
echo "writting ./reldb.src/compute.c"
cat > ./reldb.src/compute.c << '\Rogue\Monster\'
/* 
	compute.c -- implements the compute and select commands

	Pretty trivial program -- just reads the name-line and
	generates an awk-script saying 'name1=$1;name2=$2;...' and
	then the compute- or select-statement.

Author: gunnar@hafro (way back then; probably 1987)
	1989: I guess I shouldn't be writing to a string, but plead
	ignorance at the time...

*/
#include <stdio.h>
#include <signal.h>
#define MAXLINE 1000
char	*skrarnafn="tmp.......";	/* temporary file for awk-command */
main(argc,argv)
int	argc;
char	*argv[];
{
	char	inpline[MAXLINE];	/* input line */
	char	*ptr;			/* pointer into input line */
	int	select;			/* =0 if compute, =1 if select */
	int	i=1;			/* field number */
	int	die();			/* procedure to deal with exit */
	FILE	*fp,*fopen(),*popen();

	signal(SIGINT,die);
	if(strcmp(argv[0],"select"))
		select=0;
	else
		select=1;
	sprintf(&skrarnafn[3],"%07d",getpid());
	if((fp=fopen(skrarnafn,"w"))==NULL)
		errlog("Cannot open temporary file\n");
	gets(inpline);
	puts(inpline);			/* echo 1st header line */
	fprintf(fp,"awk 'BEGIN {FS=\"	\";OFS=\"	\"}\n{");
	ptr=inpline;
	do {
		while(*ptr!='\t'&&*ptr!='\0'&&*ptr!='\n')
			putc(*ptr++,fp);
		fprintf(fp,"=$(%d);",i);
		if(*ptr=='\t')
			*ptr++;
		i++;
	} while(*ptr!='\n'&&*ptr!='\0');
	if(select)
		fprintf(fp,"if(%s)print ",argv[1]);	/* select stmnt */
	else
		fprintf(fp,"%s;print ",argv[1]);	/* compute stmnt */
	ptr=inpline;
	do {
		if(*ptr=='\t')
			putc(',',fp);
		else
			putc(*ptr,fp);
		ptr++;
	} while(*ptr!='\n'&&*ptr!='\0');
	fprintf(fp,"}'\n");
	fclose(fp);
	chmod(skrarnafn,0777);		/* make file executable */
	gets(inpline);
	puts(inpline);			/* echo 2nd header line */
	fflush(stdout);
	if((fp=popen(skrarnafn,"w"))==NULL)		/* start up awk */
		errlog("Cannot start up awk\n");
	while(gets(inpline)!=NULL){
		fputs(inpline,fp);
		fputc('\n',fp);
	}
	pclose(fp);
	wait(0);			/* wait for awk to finish */
	die();
}
errlog(s)
char *s;
{
	fprintf(stderr,"%s",s);
	exit(1);
}
die(){
	unlink(skrarnafn);
	exit(0);
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/compute.c"
fi
if `test ! -s ./reldb.src/count.c`
then
echo "writting ./reldb.src/count.c"
cat > ./reldb.src/count.c << '\Rogue\Monster\'
/*
	Program to count the number of identical lines
						 */ 
#include <stdio.h>
#define MAXLIN 500
main(){
	int count;			/* counter for equal lines */
	char line[MAXLIN],prev[MAXLIN];	/* current and previous lines */

	fgets(line,MAXLIN,stdin);	/* get 2 reldb header lines */
	printf("count\t%s",line);	/* and prepend count header */
	fgets(line,MAXLIN,stdin);
	printf("-----\t%s",line);
	count=1;			/* initialize counter */
	fgets(prev,MAXLIN,stdin);
	while(fgets(line,MAXLIN,stdin)!=NULL){
		if(strcmp(line,prev)){	/* 1 = not same as before */
			printf("%d\t%s",count,prev);
			strcpy(prev,line);
			count=1;
		} else
			count++;
	}
	printf("%d\t%s",count,prev);
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/count.c"
fi
if `test ! -s ./reldb.src/README`
then
echo "writting ./reldb.src/README"
cat > ./reldb.src/README << '\Rogue\Monster\'
This is reldb, a collection of programs to handle simple relational database
operations.

Shell scripts are stored with a .sh subscript, which is
stripped off upon install.

Edit the Makefile, in particular, set BINDIR to where you want
the binaries and scripts to go. Typing 'make' will compile and install.

Files:

Makefile		The Makefile (did you guess ?)
README			This file
addcol.sh		Script to add named columns to table
addup.c			Adds up some columns (part of subtotal).
bplokk.sh		Version of plokk for large numbers (even text).
check.sh		Checks sanity of named tables.
columnlist.sh		Lists names of columns in table.
compute.c		Computes new values into columns.
count.c			Counts repeated lines (c.f. uniq).
dataplotpre.sh		Reldb interface |Stat's dataplot.
dbdict.sh		Preliminary "data base dictionary"
dbe.add.sh		Add to database.
dbe.change.sh		Change table.
invert.sh		Inverse matrix command (invert).
joinle.c		Special join, good for length distributions.
jointable.sh		Reldb version of join.
math.sh			Compute simple statistics on table.
matrix.c		Go from (frequency,x,y) to matrix.
mulregpre.sh		Reldb interface to |Stat's regress program.
number.sh		Add a column with a linenumber (cf nl).
pairpre.sh		Reldb interface to |Stat's pair program.
plokk.c			Program to select lines according to list.
preplot.sh		Reldb interface to |Stat's dataplot.
project.c		Project columns out of a table.
recode.c		Recode a column according to list.
regress.c		Simple linear regression.
rename.sh		Rename columns.
see.sh			Display tabs etc.
sideview.sh		Display a table sideways.
sorttable.sh		Sort a table.
subtotal.c		Subtotal some columns.
union.sh		Append one table to another

Someone please suggest a better name for this "package".

The directory ../testdb contains some scripts to test the
scripts and programs. Go there and type 'make', possibly after modifying 
BINDIR in the Makefile.
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/README"
fi
if `test ! -s ./reldb.src/dataplotpre.sh`
then
echo "writting ./reldb.src/dataplotpre.sh"
cat > ./reldb.src/dataplotpre.sh << '\Rogue\Monster\'
read x y
read dum
dataplot -n x$x -n y$y
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/dataplotpre.sh"
fi
if `test ! -s ./reldb.src/dbdict.sh`
then
echo "writting ./reldb.src/dbdict.sh"
cat > ./reldb.src/dbdict.sh << '\Rogue\Monster\'
awk 'BEGIN{FS="	"}
NR==1{for(i=1;i<=NF;i++){
	ind[i]=$(i)
	lengd[i]=length($(i))
	}
	svidafj=NF;
     }
NR>2{for(i=1;i<=NF;i++)
	if(length($(i))>lengd[i])lengd[i]=length($(i));
    }
END{	print "Atridi	Lengd"
	print "------	-----"
	for(i=1;i<=svidafj;i++)
		print ind[i]"	"lengd[i]
   }' 
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/dbdict.sh"
fi
if `test ! -s ./reldb.src/dbe.add.sh`
then
echo "writting ./reldb.src/dbe.add.sh"
cat > ./reldb.src/dbe.add.sh << '\Rogue\Monster\'
:
#
# dbe.add
#
# Usage: dbe.add file
#
# Type ctrl-C to quit
#
# Method:
#
# First read the reldb header fro the file
#
# Then go into an everlasting loop, reading each field from the
# terminal. After a record has been read, it is echo-ed to the end of the file.
#
read x < $1
while(true)
do
	record=""
	tput clear
	for fld in $x
	do
		echo "$fld : \c"
		read temp
		record="$record	$temp"
	done
	record=`echo "$record"|sed 's/^	//'`
	echo "$record" >> $1
done
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/dbe.add.sh"
fi
if `test ! -s ./reldb.src/dbe.change.sh`
then
echo "writting ./reldb.src/dbe.change.sh"
cat > ./reldb.src/dbe.change.sh << '\Rogue\Monster\'
#!/bin/sh
# dbe.change
#
# Useage : dbe.add file
#
# Control-C is used to quit
#
# Method:
#
# First read the Prelude header from the file
#
# Loop over all records in the file.
#     Within each record, loop over all items in the record and 
#     ask whether this item should be modified.
#

# Exactly one of the following should be set:
#  TERMINATOR='\c'
INITIATOR='-n'
# Also set one of the following:
CLEAR=clear
#CLEAR=tput clear

trap "rm -f tempedit$$ tempoutput$$" 15 2 1 
cp $1 tempedit$$
lines=`wc -l < $1`
header=`sed '1{
s/ /_/g
q
}' < $1`
(

read dumline
echo "$dumline" > tempoutput$$
read dumline
echo "$dumline" >> tempoutput$$
line=2
while [ $line -lt $lines ]
do
	read inrec
	record=""
	$CLEAR
	for fld in $header
	do
		infield=`echo "$inrec" | sed 's/	.*//'`
		echo $INITIATOR "$fld (was $infield) : $TERMINATOR"
		read temp < /dev/tty
		if [ X"$temp" = X ]
		then
			record="$record	$infield"
		else
			record="$record	$temp"
		fi
		inrec=`echo "$inrec" | sed 's/^[^	]*	//'`
	done
	record=`echo "$record"|sed 's/^	//'`
	echo "$record" >> tempoutput$$
	line=`expr $line + 1`
done
) < tempedit$$ 
mv tempoutput$$ $1
rm -f tempedit$$
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/dbe.change.sh"
fi
if `test ! -s ./reldb.src/joinle.c`
then
echo "writting ./reldb.src/joinle.c"
cat > ./reldb.src/joinle.c << '\Rogue\Monster\'
/* program to join many length distributions into one file.
	Just for fun, we compute these as a percentage distribution.

	Use: joinle files

	The only thing to watch out for is that lines may be
	missing in some files and the max/min-lengths will
	not be the same in all files.

Those not concerned with marine research might not be so hot
on length distributions -- let me know if you can transform this
into something more generally useful.
*/
#include <stdio.h>
#define MAXFILES 50			/* max # of files */
#define MAXLEN=350			/* max fish length*/
#define MAXLINE 1000			/* max length of input line */
int matrix[MAXLEN][MAXFILES]; /*Matrix of length distributions */
main(argc,argv)
int argc;
char **argv;
{
	FILE *fp;
	FILE *fopen();
	char **filelist=argv;
	char *curfile;
	
	int minlen=999999;
	int maxlen= -999999;
	int le,colnr;			/* indices into file no & length */
	int fj;
	int debug=0;			/* -d gives debug */
	char inpline[MAXLINE];

	int totals[MAXFILES];

	curfile= *++filelist;
	if(!strncmp(*filelist,"-d",2)){
		debug=1;
		*filelist++;
		*argv++;
		argc--;
	}

	/* Now go through all the files */

	for(colnr=1;colnr<argc;colnr++) {
		/* first verify that the next argument is a file */
		curfile= *filelist;
		if(debug)fprintf(stderr,"Next file, %s", curfile);
		if(debug)fprintf(stderr,".a.");
		if((fp = fopen(*filelist++,"r"))==NULL){
			fprintf(stderr,"Cannot open named file, %s\n",curfile);
			exit(1);
		}
		totals[colnr]=0;
		if(debug)fprintf(stderr,".b.");
		if(debug)fprintf(stderr,"Reading input file %s",curfile);
		if(debug)fprintf(stderr,".c.");
		fgets(inpline,MAXLINE,fp);	/* skip header */
		fgets(inpline,MAXLINE,fp);	/* skip header */
		if(debug)fprintf(stderr,".d.");
		while(fgets(inpline,MAXLINE,fp)!=NULL){
			if(debug)fprintf(stderr,".e.");
			sscanf(inpline,"%d %d",&le,&fj);
			if(le<0 || le > MAXLEN){
				fprintf(stderr,"Illegal length in file %s\n",*--filelist);
				fprintf(stderr,"Line is %s\n",inpline);
				exit(1);
			}
			if(le<minlen)minlen=le;
			if(le>maxlen)maxlen=le;
			matrix[le][colnr]=fj;
			totals[colnr]+=fj;
		}
		fclose(fp);
		if(debug)fprintf(stderr,"\n");
	}
	printf("le");
	for(colnr=1;colnr<argc;colnr++){
		printf("	%s",*++argv);
	}
	printf("\n");
	printf("--");
	for(colnr=1;colnr<argc;colnr++){
		printf("	--------");
	}
	printf("\n");
	for(le=minlen;le<=maxlen;le++){
		printf("%d",le);
		for(colnr=1;colnr<argc;colnr++){
			printf("	%.2lf",100.*(double)matrix[le][colnr]/
				(double)totals[colnr]);
		}
		printf("\n");
	}
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/joinle.c"
fi
if `test ! -s ./reldb.src/jointable.sh`
then
echo "writting ./reldb.src/jointable.sh"
cat > ./reldb.src/jointable.sh << '\Rogue\Monster\'
trap "rm tmp$$ haus$$" 2 14 15
opt=""
case $1 in
	'-n'|'-a1'|'-a2')
		opt=$1
		shift
		;;
esac
sed 1q < $1 | tr '\012' '	'  >haus$$
sed 's/^[^	]*	//
1q' < $2 >>haus$$
sed 'p
s/[^	]/-/g' < haus$$
sed '1,2d' < $2 >tmp$$
sed '1,2d' < $1 | join $opt -t"	" - tmp$$ 
rm tmp$$ haus$$

\Rogue\Monster\
else
  echo "will not over write ./reldb.src/jointable.sh"
fi
if `test ! -s ./reldb.src/math.sh`
then
echo "writting ./reldb.src/math.sh"
cat > ./reldb.src/math.sh << '\Rogue\Monster\'
#!/bin/sh
#
# math -- compute some statistics on a table.
#
# BUG: <tab><tab> is used as a zero -- should be missing

awk 'BEGIN {FS="	";OFS="	"}
NR==1	{print $0"	Type";totf=NF}
     NR==2	{print $0"	----";
	 	 for(i=1;i<=NF;i++){
				max[i]= -1e64;
				min[i]=1e64;
		}}
     NR>2	{for(i=1;i<=NF;i++){
			if($(i)!=""){
				sum[i]+=$(i);
				sum2[i]+=$(i)*$(i);
				freq[i]++;
				if($(i)>max[i])
					max[i]=$(i);
				if($(i)<min[i])
					min[i]=$(i);
			}
		}}
      END	{for(i=1;i<=totf;i++)
			printf("%d\t",freq[i]);
		 printf("Freq\n");
      		 for(i=1;i<=totf;i++)
		 	if(sum[i]==int(sum[i]))
				printf("%d\t",sum[i]);
			else
				printf("%f\t",sum[i]);
		 printf("Sum\n");
      		 for(i=1;i<=totf;i++){
			mean=sum[i]/freq[i]
			if(mean=int(mean))
				printf("%d\t",sum[i]/freq[i]);
			else
				printf("%f\t",sum[i]/freq[i]);
		 }
		 printf("Mean\n");
      		 for(i=1;i<=totf;i++){
			stdev=sqrt((sum2[i]-sum[i]*sum[i]/freq[i])/(freq[i]-1));
			if(stdev>1&&stdev<10)
				printf("%.5f\t",stdev);
			else
				printf("%f\t",stdev);
		 }
		 printf("Stddev\n");
      		 for(i=1;i<=totf;i++)
			if(max[i]==int(max[i]))
				printf("%d\t",max[i]);
			else
				printf("%f\t",max[i]);
		 printf("Maximum\n");
      		 for(i=1;i<=totf;i++)
			if(min[i]==int(min[i]))
				printf("%d\t",min[i]);
			else
				printf("%f\t",min[i]);
		 printf("Minimum\n");
		}
'
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/math.sh"
fi
if `test ! -s ./reldb.src/matrix.c`
then
echo "writting ./reldb.src/matrix.c"
cat > ./reldb.src/matrix.c << '\Rogue\Monster\'
/*
	matrix:

	A program for setting up a simple frequency table,
	based on (count,x,y)-data
								*/
#include <stdio.h>
#define MAXX 250
#define MAXY 50
#define MINX 0
#define MINY 0
#define MAXLIN 500
#define MAXNAM 10
main(argc,argv)
int argc;
char *argv[];
{
	char line[MAXLIN],xname[MAXNAM],yname[MAXNAM],dum[MAXNAM];
	char *format="\t%f";	/* Output table default format */
	
	static float freq[MAXX][MAXY];	/* the frequencies */
	float marg[MAXX];		/* marginal frequencies */
	int x,y;		/* input data : x,y, freq of x,y */
	float n;
	int testmarg=1;		/* =1=>skip empty lines =0=>print them*/
	int minx,maxx,miny,maxy;/* computed bounds on input data */
	
	while(--argc){
		if(argv[1][0]=='-'){
			if(argv[1][1]=='e')
				testmarg=0;	/* print empty lines */
			else{
				fprintf(stderr,"Incorrect argument to matrix\n");
				fprintf(stderr,"Usage : matrix [-e] [format]\n");
				fprintf(stderr,"         -e : print empty lines\n");
				fprintf(stderr,"          format : C printf format, default : %s\n",format);
				exit(1);
			}
		} else {
			format=argv[1];
		}
		argv++;
	}
	fgets(line,MAXLIN,stdin);	/* Reldb header line */
	sscanf(line,"%s %s %s",dum,xname,yname);/* get names of columns */
	fgets(line,MAXLIN,stdin);	/* Reldb dash-line */

	minx=MAXX;maxx=MINX;miny=MAXY;maxy=MINY;
	while(fgets(line,MAXLIN,stdin)!=NULL){
		sscanf(line,"%f %d %d",&n,&x,&y);
		if(x>=MAXX||y>=MAXY){
			fprintf(stderr,"Bound error : %s\n",line);
			continue;
		}
		++x;++y;
		freq[x][y]+=n;
		marg[x]+=n;
		if(x>=maxx)maxx=x;
		if(y>=maxy)maxy=y;
		if(x<=minx)minx=x;
		if(y<=miny)miny=y;
	}
	printf("%s",xname);
	for(y=miny-1;y<maxy;){
		printf("\t%s%d",yname,y++);
	}
	printf("\n--");
	for(y=miny-1;y<maxy;y++){
		printf("\t----");
	}
	printf("\n");
	for(x=minx;x<=maxx;x++){
		if(marg[x]==0&&testmarg)
			continue;		/* skip empties */
		printf("%d",x-1);
		for(y=miny-1;y<maxy;){
			printf(format,freq[x][++y]);
		}
		printf("\n");
	}
} /* main */
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/matrix.c"
fi
if `test ! -s ./reldb.src/columnlist.sh`
then
echo "writting ./reldb.src/columnlist.sh"
cat > ./reldb.src/columnlist.sh << '\Rogue\Monster\'
#!/bin/sh
#
# columnlist.sh
#
# trivial sed-command to list column names of a table.
#
sed '1s/	/\
/g
1q'
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/columnlist.sh"
fi
if `test ! -s ./reldb.src/mulregpre.sh`
then
echo "writting ./reldb.src/mulregpre.sh"
cat > ./reldb.src/mulregpre.sh << '\Rogue\Monster\'
#!/bin/sh
#
# neat little script for interfacing with |Stat's "regress"
read x
read dummy
/usr/stat/bin/regress -p $x
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/mulregpre.sh"
fi
if `test ! -s ./reldb.src/number.sh`
then
echo "writting ./reldb.src/number.sh"
cat > ./reldb.src/number.sh << '\Rogue\Monster\'
#!/bin/sh
#
# number -- add a number column
awk '
NR == 1	{print "nr	"$0}
NR == 2	{print "--	"$0}
NR > 2	{print NR-2"	"$0}' < $1
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/number.sh"
fi
if `test ! -s ./reldb.src/pairpre.sh`
then
echo "writting ./reldb.src/pairpre.sh"
cat > ./reldb.src/pairpre.sh << '\Rogue\Monster\'
:
# Reldb version of unixstat's (|Stat) pair
read x y
read dum
pair -p -x $y -y $y
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/pairpre.sh"
fi
if `test ! -s ./reldb.src/plokk.c`
then
echo "writting ./reldb.src/plokk.c"
cat > ./reldb.src/plokk.c << '\Rogue\Monster\'
/* 
	Program to select lines according to values in the first column
	of each line.

	Usage : plokk fnam < file

	file = name of data file

	fnam = name of file containing values to be selected
							*/
#include <stdio.h>

main(argc,argv)
int argc;
char *argv[];
{
	char lina[1000];	/* input line*/
	int n;			/* first value in a data line */
	
	int select[5000];	/* 1=values to select 0=skip*/
	int nsel;		/* running value to select */

	FILE *fp,*fopen();

	if((fp=fopen(argv[1],"r"))==NULL){	/* open selection file */
		fprintf(stderr,"Usage : plokk selfil < datfil\n");
		exit(-1);
	}

	nsel=0;					/* initialize selection */
	while(nsel<5000)
		select[nsel++]=0;

	fgets(lina,1000,fp);			/* read selection file */
	fgets(lina,1000,fp);
	while(fgets(lina,1000,fp)!=NULL){
		sscanf(lina,"%d",&nsel);
		if(nsel< -1 || nsel> 5000){
			fprintf(stderr,"plokk : index in selection file out of bounds %d\n",nsel);
			exit(1);
		}
		select[nsel+1]=1;
	}
	fclose(fp);

	fgets(lina,1000,stdin);
	printf("%s",lina);
	fgets(lina,1000,stdin);
	printf("%s",lina);
	while(fgets(lina,1000,stdin)!=NULL){	/* perform selection */
		sscanf(lina,"%d",&n);
		if(n< -1 || n > 5000){
			fprintf(stderr,"plokk : index in data file out of bounds %d\n",n);
			exit(1);
		}
		if(select[n+1])
			printf("%s",lina);
	}
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/plokk.c"
fi
if `test ! -s ./reldb.src/preplot.sh`
then
echo "writting ./reldb.src/preplot.sh"
cat > ./reldb.src/preplot.sh << '\Rogue\Monster\'
#!/bin/sh
#
# neat little script for interfacing with |Stat's dataplot.
read x y
read dum
dataplot -n x$x -n y$y$ $*
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/preplot.sh"
fi
if `test ! -s ./reldb.src/project.c`
then
echo "writting ./reldb.src/project.c"
cat > ./reldb.src/project.c << '\Rogue\Monster\'
/*
	project:

	Author; johanna@hafro.is (1987?)
*/
#include <stdio.h>
#define MAXLINE 4096
main(argc,argv)
    int argc;
    char *argv[];
{
       int i;
       int h;
       int a;
       char line[MAXLINE];
       char tabv[1000][100];
       int posv[1000];

       i=0;

       argc--;

       header_lines(argc,argv);
       getline(line,MAXLINE,h,a);
       velja_dalka(tabv,line,&h,&a);
       gera_dalka(argc,argv,tabv,&h);
       cal_pos_val(argc,argv,tabv,posv);
       getline(line,MAXLINE,h,a);
       while((i = getline(line,MAXLINE,h,a)) > 0)
       {
          project_dalka(argc,posv,line);
       }

       exit(0);
}


header_lines(argc,argv)
int argc;
char *argv[];
{
int i;
int l;
int s;
int j;

i=j=s=l=0;

for(i=1;i <= argc;i++)
   {
    printf("%s",argv[i]);
    if(i==argc)
      printf("\n");
    else
      printf("\t");
   }
for(j=1;j <= argc;j++)
   {
    l=strlen(argv[j]);
    for(s=1;s <= l;s++)
        printf("-");
    if(j==argc)
       printf("\n");
    else
       printf("\t");
   }
}


velja_dalka(tabv,line,h,a)
char tabv[1000][100];
char line[MAXLINE];
int *h;
int *a;
{
    int i;
    int j;

    *h=0;
    i=0;

    do
    {
       j=0;
       while((line[i] != '\t') && (line[i] != '\n'))
       {
            tabv[*h][j]=line[i];
            j++;
            i++;
       }
       tabv[*h][j]='\0';
       (*h)++;
    }
    while(line[++i] != '\0');
    tabv[*h][0]='\0';
    --h;
    (*a)=(*h);
}



gera_dalka(argc,argv,tabv,h)
int argc;
char *argv[];
char tabv[1000][100];
int *h;
{
     int x;
     int y;
     char *strcpy();

     x=y=0;
     for(x=1;x <= argc;x++)
        {
          y=0;
          while((tabv[y][0] != '\0') && (strcmp(argv[x],tabv[y]) != 0))y++;
          if (strcmp(argv[x],tabv[y]) == 0)
          {
          }
          else
          {
             strcpy(tabv[y],argv[x]);
             (*h)++;
          }
        }
}



cal_pos_val(argc,argv,tabv,posv)
int argc;
char *argv[];
char tabv[1000][100];
int posv[1000];
{
    int k;
    int l;

    for(k=1;k <= argc;k++)
       {
         l=0;

         while((strcmp(argv[k],tabv[l]) != 0) && (l < 1000))l++;

         l++;
         posv[k]=l;
       }
}


project_dalka(argc,posv,line)
int argc;
int posv[1000];
char line[MAXLINE];
{
  int d;
  int t;
  int l;
  
  for (d=1;d <= argc;d++)
  {
      l=0;
      for (t=1;t < posv[d];t++)
      {
           while ((line[l] != '\t') && (line[l] != '\0')) l++;
                 l++;
      }
      while ((line[l] != '\t') && (line[l] != '\n'))
            putchar(line[l++]);
      if (d < argc)
          putchar('\t');
      else
          putchar('\n'); 
              
   }
}


getline(s,lim,h,a)
char s[];
int lim;
int h;
int a;
{
  int c;
  int i;
  int j;
  char *strcat();

  j=0;
  c=0;
  i=0;

  while (--lim > 0 && (c=getchar()) != EOF && c != '\n')
      s[i++]=c;

  if (c == '\n')
      s[i++] = c;
  s[i] = '\0';
  for(j=a;j < h;j++)
     {
     strcat(s,"\t");
     }

  return(i);
}
\Rogue\Monster\
else
  echo "will not over write ./reldb.src/project.c"
fi
echo "Finished archive 2 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.