v20i005: Relational database and graphing tools, Part02/03
Rich Salz
rsalz at uunet.uu.net
Tue Sep 19 07:30:34 AEST 1989
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 at 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 at hafro.is (March, 1989) */
/* Prepared for redistribution by gunnar at 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 at hafro.is (June, 1989) */
/* Prepared for redistribution by gunnar at 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 at hafro.is (June, 1989) */
/* Prepared for redistribution by gunnar at 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 at 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 at 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 at 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 at 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 at 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 at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list