rsalz@uunet.uu.net (Rich Salz) (03/14/89)
Submitted-by: Jim McBeath <voder!sci!gumby!jimmc> Posting-number: Volume 18, Issue 15 Archive-name: treepar/part01 TREEPAR is a place and route (and plot) package for tree structured data. It is primarily intended as a companion program to GENEAL, a genealogy program. NOTE: Treepar uses the SPIN package (Simple Programmable INterface). If you don't have it, you won't be able to build treepar. #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 3)." # Contents: MANIFEST Makefile README main.c misc.c network.h plot.c # plot.h plotHP.c plotSIZE.c plotTEST.c plotX.c sample.tf tfile.c # tfile.h tklex.h # Wrapped by rsalz@fig.bbn.com on Thu Mar 9 15:55:33 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(716 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 X Makefile 1 X README 1 X main.c 1 X misc.c 1 X network.c 2 X network.h 1 X par.c 3 X plot.c 1 X plot.h 1 X plotHP.c 1 X plotSIZE.c 1 X plotTEST.c 1 X plotX.c 1 X sample.tf 1 X tfile.c 1 X tfile.h 1 X tklex.c 2 X tklex.h 1 X treepar.n 2 END_OF_FILE if test 716 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(3327 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X#Makefile for treepar X# 28.Jul.87 jimmc Initial definition X# 2.Aug.87 jimmc Add backup tag X# 20.Jan.88 jimmc Add man tag X# 1.Mar.88 jimmc Fix up shar stuff X XPROGRAM = treepar XDEST = . X XXINCDIR = /u8/X/X10R4/include X#NOTE:non-standard X directory; typically is /usr/include/X XXLIB = /u8/X/X10R4/lib/libX.a X#Typically is /usr/lib/libX.a X XMKMF = mkmf X XCLASH = clash X XSHAR = shar X XMAKE = make $(MFLAGS) XMAKEFILE = Makefile X XSPINDIR = ../spin X XBKPMACH = wheel XBKPDIR = geneal/treepar.bak X X# careful with this variable. it is really set down in target "depend:" XCFLAGS = $(CCOPTS) -I../spin -I/u8/X/X10R4/include X XINCLUDE = -I$(SPINDIR) -I$(XINCDIR) XCCOPTS = -g -DX10 X XLINKER = cc X XLINTFLAGS = $(INCLUDE) $(LINTOPTS) XLINTOPTS = -bauz X XSRCS = main.c \ X misc.c \ X network.c \ X par.c \ X plot.c \ X plotHP.c \ X plotSIZE.c \ X plotTEST.c \ X plotX.c \ X tfile.c \ X tklex.c X XOBJS = main.o \ X misc.o \ X network.o \ X par.o \ X plot.o \ X plotHP.o \ X plotSIZE.o \ X plotTEST.o \ X plotX.o \ X tfile.o \ X tklex.o X XHDRS = network.h \ X plot.h \ X tfile.h \ X tklex.h X XEXTHDRS = ../spin/xalloc.h \ X /usr/include/ctype.h \ X /usr/include/stdio.h \ X /usr/include/string.h \ X /usr/include/varargs.h X XLIBS = $(SPINDIR)/spin.a X XLINTLIBS = $(SPINDIR)/llib-lspin.a.ln X XXLINTLIBS = X XMANSRC = treepar.n XDOCFILES = README $(MANSRC) sample.tf XSHARFILES1 = $(DOCFILES) $(MAKEFILE) $(HDRS) [a-o]*.c XSHARFILES2 = [p-z]*.c XSHAROUT1 = $(PROGRAM).1.sh XSHAROUT2 = $(PROGRAM).2.sh X Xdefault: $(PROGRAM) X Xall: $(PROGRAM) X X$(PROGRAM): $(OBJS) $(LIBS) X @echo -n "Loading $(PROGRAM) ... " X @rm -f $(PROGRAM) X @$(LINKER) $(CFLAGS) $(OBJS) $(LIBS) $(XLIB) -lm \ X -o $(PROGRAM).new X @mv -f $(PROGRAM).new $(PROGRAM) X @echo "done" X Xinstall: $(PROGRAM) X @echo Installing $(PROGRAM) in $(DEST) X @install -m 770 -c $(PROGRAM) $(DEST) X Xdepend: $(XDEP) X @echo Updating $(MAKEFILE) ... X @$(MKMF) -f $(MAKEFILE) \ X CFLAGS='$$(CCOPTS) $(INCLUDE)' X# PROGRAM makes mkmf use p.Makefile template X# PROGRAM=$(PROGRAM) X Xlint:; lint $(LINTFLAGS) $(SRCS) $(LINTLIBS) X Xclash:; $(CLASH) $(SRCS) $(HDRS) X Xman: treepar.man X Xtreepar.man: $(MANSRC) X nroff -man $(MANSRC) > treepar.man.new X mv treepar.man.new treepar.man X Xshar: $(SHAROUT1) $(SHAROUT2) X X$(SHAROUT1): $(SHARFILES1) X $(SHAR) -n 1 -e 2 $(SHARFILES1) > $(SHAROUT1) X X$(SHAROUT2): $(SHARFILES2) X $(SHAR) -n 2 -e 2 $(SHARFILES2) > $(SHAROUT2) X Xtidy:; @rm -f $(OBJS) X Xclean: tidy X @rm -f $(PROGRAM) X Xprint:; @pr $(SRCS) $(HDRS) X Xtags: $(HDRS) $(SRCS); @ctags $(HDRS) $(SRCS) X Xbackup:; tar cf - $(HDRS) $(SRCS) $(MAKEFILE) | \ X rsh $(BKPMACH) 'cd $(BKPDIR); tar xBf -' X X### Xmain.o: /usr/include/stdio.h ../spin/xalloc.h Xmisc.o: /usr/include/stdio.h ../spin/xalloc.h Xnetwork.o: /usr/include/stdio.h /usr/include/ctype.h /usr/include/string.h \ X ../spin/xalloc.h network.h tklex.h tfile.h plot.h Xpar.o: /usr/include/ctype.h network.h ../spin/xalloc.h Xplot.o: /usr/include/string.h plot.h XplotHP.o: /usr/include/stdio.h plot.h XplotSIZE.o: /usr/include/stdio.h plot.h XplotTEST.o: /usr/include/stdio.h plot.h XplotX.o: plot.h Xtfile.o: /usr/include/stdio.h /usr/include/varargs.h /usr/include/string.h \ X ../spin/xalloc.h tklex.h tfile.h Xtklex.o: /usr/include/stdio.h /usr/include/ctype.h /usr/include/string.h \ X tklex.h END_OF_FILE if test 3327 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(1961 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XThe TREEPAR Program 1.Mar.88 XWritten by Jim McBeath (jimmc) at SCI X XThis is version 1.1 of TREEPAR. X XTREEPAR is a place and route (and plot) package for tree structured Xdata. It is primarily intended as a companion program to GENEAL, Xa genealogy program. X XNOTE: Treepar uses the SPIN package (Simple Programmable INterface). XIf you don't have it, you won't be able to build treepar. X XFiles of interest: X *.[ch] The source files for treepar. X Makefile Exactly that. X README What you are looking at right now. X treepar.n Source for man page. Describes (briefly) what X treepar is all about. Gives list of switches. X Use "make man" to create treepar man file (treepar.man). X sample.tf A sample file output by geneal, to be read in and X plotted by treepar. X XWhat to do (after unpacking): X1. Use "make man" to create treepar.man from treepar.n. Read it. X2. Edit the Makefile and set SPINDIR to point to the directory containing X the spin files (xalloc.h, spin.h, spin.a, llib-lspin.a.ln). X By default this is ../spin. X If you do not have X10, you will have to disable the X driver. X Do this by removing "-DX10" from the CCOPTS line in the Makefile. X You may also wish to change the default arguments to the NPlot X command in main.c. X If you DO have X10, you will need to change the XINCDIR and XLIB lines X which define where the X files are located. X3. Make the program. You should be able to simply issue a "make" command. X4. Run treepar and test it on the sample data file with the following X commands (you enter the stuff after the ">" prompt): X >TVersion X STRING treepar v1.1 1.Mar.88 X >NRead "sample.tf" X INT 1 X >Rpar X INT 1 X >NPlot X INT 1 X >quit X5. Send me your comments, wishes, and improvements. X XTreepar has been run on a SUN3 under Sun OS3.4, and on a VAX under BSD4.2. XIf you have problems running on other systems, please let me know. X X -Jim McBeath {decwrl|oliveb|weitek|auspyr}!sci!jimmc X 1.Mar.1988 END_OF_FILE if test 1961 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(2578 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X/* main program for treepar X * X * 28.Jul.87 jimmc Initial definition X * 14.Aug.87 jimmc Add place and route stuff X * 22.Sep.87 jimmc Define F macro in this file X * 17.Oct.87 jimmc Convert to use spin interface X * 27.Jan.88 jimmc Add RFeed command X * 5.Feb.88 jimmc Moved some routines into misc.c X */ X X#include <stdio.h> X#include "xalloc.h" X Xextern char *rindex(); X Xchar *treeparVersion = "treepar v1.1 1.Mar.88"; X Xchar *Progname; X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ Xint i,j; Xchar *execval=0; X X Progname = rindex(argv[0],'/'); X if (Progname) Progname++; else Progname=argv[0]; X X PSetup(); /* init the plot drivers */ X applinit(); X X SPinitsubs(); X X for (i=1; i<argc; i++) { X if (argv[i][0]=='-') for (j=1; j>0 && argv[i][j]; j++) { X switch (argv[i][j]) { X case 'e': /* execute */ X if (argv[i][++j]) execval = argv[i]+j; X else if (++i<argc) execval = argv[i]; X else fatalerr("not enough args for -e"); X j = -1; X break; X default: X fatalerr("unknown switch %c", argv[i][j]); X } X } X else { /* not a switch */ X fatalerr("unknown argument %s", argv[i]); X } X } X X if (execval) { SPmainstring(execval); } X SPmainfile(stdin); X exit(0); X} X X/* X * arg types are: X * i - integer X * s - string X * f - float (double) X * L - list X * X * define function as F(funcname,"argstr") X * The first char of argstr is the return type X */ X X#define F(fnamez,argsz) {\ X extern fnamez();\ X SPdeffunc("fnamez",argsz,fnamez);\ X} X X#define FS(fnamez,argsz) {\ X extern char *fnamez();\ X SPdeffunc("fnamez",argsz,fnamez);\ X} X Xapplinit() X{ X/* routines to read and write the tree text files */ XF(NRead,"is"); XF(NWrite,"is"); XF(NPlot,"iS\"X\"S\"stdout\""); XF(NPlot4,"iS\"X\"S\"stdout\""); XF(NPlotXY,"iS\"X\"S\"stdout\"I2I2"); XF(PSetWindow,"vdddd"); X X/* place and route routines */ XF(RSelect,"iSN"); /* select rows for boxes and nets */ XF(RUnFeed,"i"); /* undo any feedthroughs */ XF(RFeed,"i"); /* generate feedthroughs for nets which span rows */ XF(RReFeed,"i"); /* UnFeed and Feed */ XF(RSpace,"i"); /* generate row datastructs and size them */ XF(ROrder,"iSN"); /* order the boxes within each row */ XF(RPosition,"i"); /* position boxes within the rows */ XF(RRoute,"i"); /* do the channel route */ XF(Rpar,"iSN"); /* do all of the place and route stuff */ XF(RReFeedpar,"iSN"); /* do RReFeed and the rest */ XF(RSpacepar,"iSN"); /* do RSpace and the rest */ X X/* misc routines */ XFS(TFlags,"ss"); /* set and get random flags */ XFS(TVersion,"s"); /* returns the current version string */ X X/* routines for debugging the lexical analyzer */ XF(TkDebugFile,"is"); X} X X/* end */ END_OF_FILE if test 2578 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'misc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'misc.c'\" else echo shar: Extracting \"'misc.c'\" \(617 characters\) sed "s/^X//" >'misc.c' <<'END_OF_FILE' X/* misc.c - random small routines. X * X * 5.Feb.88 jimmc Created by collecting routines from other files X */ X X#include <stdio.h> X#include "xalloc.h" X Xextern char *Progname; Xextern char *treeparVersion; Xextern char Tflag[]; X X/* VARARGS1 */ Xfatalerr(fmt,arg0) Xchar *fmt; Xchar *arg0; X{ Xchar buf[2000]; X X sprintf(buf,fmt,arg0); X fprintf(stderr,"%s: %s\n", Progname,buf); X exit(1); X} X Xchar * Xstrsav(str) Xchar *str; X{ Xchar *newstr; X X newstr = XALLOC(char,strlen(str)+1); X strcpy(newstr,str); X return newstr; X} X Xtfree(p) Xchar *p; X{ X if (!Tflag['m']) X XFREE(p); X} X Xchar * XTVersion() X{ X return treeparVersion; X} X X/* end */ END_OF_FILE if test 617 -ne `wc -c <'misc.c'`; then echo shar: \"'misc.c'\" unpacked with wrong size! fi # end of 'misc.c' fi if test -f 'network.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'network.h'\" else echo shar: Extracting \"'network.h'\" \(4541 characters\) sed "s/^X//" >'network.h' <<'END_OF_FILE' X/* network.h - definition of the network (typically a tree) structure. X * X * 28.Jul.87 jimmc Initial definition X * 1.Aug.87 jimmc Add text stuff in Nbox X * 2.Aug.87 jimmc Add path stuff X * 12.Aug.87 jimmc Add boxname and netname to conn X * 14.Aug.87 jimmc Add stuff to rows, nets; add tracks X * 19.Aug.87 jimmc Add label X * 3.Nov.87 jimmc Add rowdir, modify Npoint X * 27.Jan.88 jimmc Add FEEDTHROUGH flag X */ X X/* parflag bits */ X#define ROWSET (1<<0) /* this bit set if the row has been set */ X#define ORDERSET (1<<1) /* this bit set if the order in row has been set */ X#define BOXROW (1<<2) /* for rows, this bit set if a row of boxes */ X#define SPANSET (1<<3) /* for tracks, indicates a span has been set */ X#define POSITIONSET (1<<4) /* for boxes, when position within row is set */ X#define FEEDTHROUGH (1<<5) /* for boxes, indicates a feedthrough net */ X Xtypedef struct _Npoint { /* a point or vector value */ X int cc[2]; /* x and y */ X#define X cc[0] /* normal coords */ X#define Y cc[1] X} Npoint; X Xtypedef struct _Ngroup { /* for dynamically allocated arrays of thingies */ X int count; /* number of entries used */ X int alloc; /* number of entries allocated */ X union { X struct _Nnet **net; X struct _Nbox **box; X struct _Nconn **conn; X struct _Nrow **row; X struct _Ntrack **track; X struct _Ngroup **path; X struct _Npoint *pt; /* this one is a bit different */ X int *n; X char * *x; /* untyped version of data */ X } d; X} Ngroup; X Xtypedef struct _Nconn { /* one connector (terminal) */ X char *name; /* name of the connector */ X char *boxname; /* name of the box (used before linking) */ X struct _Nbox *box; /* pointer to box owning this connector */ X Npoint pos; /* position of this connector wrt box */ X Npoint apos; /* absolute position of this connector */ X int side; /* which side of the box (N,S,E,W)*/ X#define N 0 X#define S 1 X#define E 2 X#define W 3 X char *netname; /* name of net (used before linking) */ X struct _Nnet *net; /* the net attached to this connector */ X} Nconn; X Xtypedef struct _Nbox { /* a box */ X char *name; /* name of this box */ X Npoint size; /* size of the box */ X Npoint origin; /* origin (lower left corner) */ X char *text; /* text within the box */ X Npoint text_origin; /* origin of text relative to origin of box */ X int text_opos; /* where the text origin is wrt the text (see plot.h) */ X int rownum; /* number of the row this box is in */ X struct _Nrow *row; /* row containing this box */ X int rowpos; /* relative position of this block in that row */ X Ngroup connlist; /* associated connectors */ X int parflags; /* flags used during place/route */ X} Nbox; X Xtypedef struct _Nnet { /* one net (wire, polyline) */ X char *name; /* name of the net */ X Ngroup connlist; /* associated connectors */ X struct _Ngroup pathlist; /* a set of paths */ X int rownum; /* number of the row this net is in */ X struct _Nrow *row; /* row containing this net */ X int rowpos; /* position within that row */ X int minpos,maxpos; /* span of the net within the row */ X struct _Ntrack *track; X int parflags; /* flags used during place/route */ X int angle; X} Nnet; X Xtypedef struct _Ntrack { /* one track within a channel */ X int parflags; X Ngroup netlist; /* list of nets in this track (from which X * we can determine the used ranges) */ X int n; /* track index number in channel */ X int pos; /* track position */ X} Ntrack; X Xtypedef struct _Nrow { /* one placement row */ X int rownum; /* the number for this row */ X int size; /* size of this row (typically the small dimension) */ X int length; /* length (typically the larger dimension) */ X int pos; /* position of the row */ X Ngroup boxlist; /* boxes which are in this row */ X Ngroup netlist; /* nets which are in this row */ X int rowposmin, rowposmax; /* for relative position of boxes */ X Ngroup tracklist; /* set of tracks within a channel */ X int parflags; X} Nrow; X Xtypedef struct _Nlabel { X char *s; /* the label string */ X Npoint tsize; /* size of the label in chars */ X Npoint origin; /* lower left corner of the label */ X} Nlabel; X Xtypedef struct _Nbase { /* the handle for everything */ X Ngroup netlist; X Ngroup boxlist; X Ngroup connlist; X Ngroup rowlist; X int maxrowlength; /* length of the longest row */ X/* global parms */ X Npoint textsize; X int interrowspace; /* default space between rows */ X int rowposspace; /* mon space between boxes in a row */ X int trackspace; /* space between routing tracks */ X Nlabel label; /* label for the whole thing */ X int rowdir; /* 'V'ertical or 'H'orizontal */ X} Nbase; X X/* end */ END_OF_FILE if test 4541 -ne `wc -c <'network.h'`; then echo shar: \"'network.h'\" unpacked with wrong size! fi # end of 'network.h' fi if test -f 'plot.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plot.c'\" else echo shar: Extracting \"'plot.c'\" \(6831 characters\) sed "s/^X//" >'plot.c' <<'END_OF_FILE' X/* plot.c - plotting routines X * X * 30.Jul.87 jimmc Initial definition X * 1.Aug.87 jimmc Add PsBox, PText, change args in PInit, add HPGL driver X * 17.Aug.87 jimmc Add textsize function X * 19.Aug.87 jimmc Make text device primitive work on one line only X * 26.Aug.87 jimmc Add PSetWindow X * 22.Dec.87 jimmc Add call to PSZSetup X * 18.Jan.88 jimmc lint cleanup X */ X X#include <strings.h> X#include "plot.h" X Xextern char *malloc(); Xextern char *index(); X Xstatic PDevInfo *infobase; Xstatic PDevInfo *currentinfo; Xstatic char *currentfn; X Xstatic float Pscale; Xstatic int Poffsetx,Poffsety; Xstatic int Pbasex,Pbasey; Xstatic int TextSizeX, TextSizeY; X#define SCALEONLY(n) (int)(Pscale*((float)(n))) X#define SCALEX(x) (Poffsetx+(int)(Pscale*((float)(x-Pbasex)))) X#define SCALEY(y) (Poffsety+(int)(Pscale*((float)(y-Pbasey)))) X Xstatic double wslx=0.0; Xstatic double wshx=1.0; Xstatic double wsly=0.0; Xstatic double wshy=1.0; Xint wlx,wly,whx,why; /* window boundaries */ X Xstatic int Xbadfunc() X{ X printf("Bad function pointer in plot package\n"); X} X Xint /* 1 if OK */ XPSetType(ptype,filename) Xchar *ptype; /* plotter type */ Xchar *filename; X{ XPDevInfo *p; X X for (p=infobase; p; p=p->next) X if (strcmp(ptype,p->name)==0) break; X if (!p) { X printf("no such plot type %s\n", ptype); X return 0; X } X currentinfo = p; X if (currentfn) free(currentfn); X currentfn = malloc((unsigned)(strlen(filename)+1)); X if (!currentfn) { X printf("no memory for filename"); X return 0; X } X strcpy(currentfn,filename); X return 1; X} X XPSetWindow(lx,ly,hx,hy) /* normalized window coords (0.0 to 1.0) */ Xdouble lx,ly,hx,hy; X{ Xdouble t; X X if (hx==lx || hy==ly) return; X if (hx<lx) { t=hx; hx=lx; lx=t; } X if (hy<ly) { t=hy; hy=ly; ly=t; } X if (lx<0.0) lx=0.0; X if (hx>1.0) hx=1.0; X if (ly<0.0) ly=0.0; X if (hy>1.0) hy=1.0; X wslx=lx; X wshx=hx; X wsly=ly; X wshy=hy; X} X XPInit(lx,ly,hx,hy) Xint lx,ly; Xint hx,hy; X{ Xint devlx,devly,devhx,devhy; Xint devx,devy; Xint vx,vy; Xdouble xr,yr; X X wlx = lx + wslx*(hx-lx); /* do the window scaling */ X whx = lx + wshx*(hx-lx); X wly = ly + wsly*(hy-ly); X why = ly + wshy*(hy-ly); X vx = whx-wlx+1; /* x dimension of virtual drawing area */ X vy = why-wly+1; X if (!((*currentinfo->init)(currentfn,&devlx,&devly,&devhx,&devhy))) { X /* get device size */ X return 0; /* no init */ X } X devx = devhx-devlx+1; X devy = devhy-devly+1; X xr = ((double)devx)/((double)vx); X yr = ((double)devy)/((double)vy); X Pbasex = wlx; X Pbasey = wly; X if (xr>=yr) { /* scale to fix x */ X Pscale = yr*0.95; X Poffsetx = ((int)(0.025*((double)devx)))+devlx; X Poffsety = ((int)(0.025*((double)devy)))+devly; X } else { /* scale to fit y */ X Pscale = xr*0.95; X Poffsetx = ((int)(0.025*((double)devx)))+devlx; X Poffsety = ((int)(0.025*((double)devy)))+devly; X } X return 1; X} X XPDone() X{ X (*currentinfo->done)(); X} X XPTextSize(x,y) Xint x,y; /* width and height of one character */ X{ X TextSizeX = x; X TextSizeY = y; X (*currentinfo->textsize)(SCALEONLY(x),SCALEONLY(y)); X} X X#define ASCALE 10000 Xtypedef int Alphatype; X#define ALPH(a,l,h) (l+(int)((a*(h-l))/ASCALE)) X#define Paline(lx,ly,hx,hy) \ X (*currentinfo->line)(SCALEX(lx),SCALEY(ly),SCALEX(hx),SCALEY(hy)); X Xstatic Alphatype Xalpha(l,h,w) Xint l,h; Xint w; X{ XAlphatype a; X if (l==h) return 0; X a = (ASCALE*(w-l))/(h-l); X if (a<0) return 0; X if (a>ASCALE) return ASCALE; X return a; X} X XPLine(lx,ly,hx,hy) Xint lx,ly; Xint hx,hy; X{ Xint t; XAlphatype aly,ahy; XAlphatype alx,ahx; XAlphatype al,ah; X X if (hx<wlx || lx>whx || hy<wly || ly>why) return; X if (lx==hx) { /* vertical line */ X aly = alpha(ly,hy,wly); X ahy = alpha(ly,hy,why); X if (aly!=ahy) Paline(lx,ALPH(aly,ly,hy),hx,ALPH(ahy,ly,hy)); X } X else if (ly==hy) { /* horizontal line */ X alx = alpha(lx,hx,wlx); X ahx = alpha(lx,hx,whx); X if (alx!=ahx) Paline(ALPH(alx,lx,hx),ly,ALPH(ahx,lx,hx),hy); X } X else { /* angled line */ X#define ORDER(l,h) { \ X if (l>h) { \ X t = l; \ X l = h; \ X h = t; \ X }} X aly = alpha(ly,hy,wly); X ahy = alpha(ly,hy,why); X alx = alpha(lx,hx,wlx); X ahx = alpha(lx,hx,whx); X ORDER(aly,ahy) X ORDER(alx,ahx) X al = (alx>aly)?alx:aly; /* use highest low and lowest high */ X ah = (ahx<ahy)?ahx:ahy; X if (al!=ah) X Paline(ALPH(al,lx,hx),ALPH(al,ly,hy), X ALPH(ah,lx,hx),ALPH(ah,ly,hy)); X } X} X XPBox(lx,ly,hx,hy) Xint lx,ly; Xint hx,hy; X{ X PLine(lx,ly,lx,hy); X PLine(lx,hy,hx,hy); X PLine(hx,hy,hx,ly); X PLine(hx,ly,lx,ly); X} X X/* Characters are clipped based on the lower left corner point of each char. */ XPTextLine(lx,ly,text) Xint lx,ly; /* lower left corner of text line */ Xchar *text; X{ Xint hx; Xint l; Xint oldc=0; X X if (!text || !*text) return; X l = strlen(text); X hx = lx + l*TextSizeX; X if (hx<wlx || lx>=whx || ly<wly || ly>=why) return; /* out */ X if (lx<wlx) { /* hangs out the left, lets clip that part */ X l = (wlx-lx+TextSizeX-1)/TextSizeX; X /* number of chars to clip */ X text += l; X lx += l*TextSizeX; X } X if (hx>whx) { /* hangs out the right */ X l = (hx-whx)/TextSizeX; X l = strlen(text)-l; X oldc = text[l]; X text[l] = 0; X } X (*currentinfo->text)(SCALEX(lx),SCALEY(ly),text); X if (oldc) text[l]=oldc; /* restore if we changed it */ X} X XPText(x,y,p,text) Xint x,y; Xint p; /* position of (x,y) in text (see plot.h) */ Xchar *text; X{ Xint sx,sy; /* size of the text block */ Xchar *t,*e; Xint len; X X sx = sy = 0; /* find the size of the text block */ X for (t=text;t;t=e) { X sy++; /* count lines */ X e = index(t,'\n'); X if (e) len = (e++)-t; X else len = strlen(t); X if (len>sx) sx=len; /* count characters */ X } X if (sx==0 || sy==0) return; X sx *= TextSizeX; X sy *= TextSizeY; X switch (p) { /* convert (x,y) to point to lower left */ X case N: x -= sx/2; y -= sy; break; X case S: x -= sx/2; break; X case E: x -= sx; y -= sy/2; break; X case W: y -= sy/2; break; X case NE: x -= sx; y -= sy; break; X case NW: y -= sy; break; X case SE: x -= sx; break; X case SW: break; /* this is the default location */ X case C: x -= sx/2; y -= sy/2; break; X default: break; /* assume default for random stuff */ X } X y += sy; /* point to upper left corner */ X while (text) { X y -= TextSizeY; /* point to lower left for this line */ X e = index(text,'\n'); X if (e) *e='\000'; X PTextLine(x,y,text); X if (e) *(e++)='\n'; /* restore */ X text = e; X } X} X XPDevInfo * XPnew() X{ XPDevInfo *p; X X p = (PDevInfo *)malloc(sizeof(PDevInfo)); X if (!p) { X printf("no more memory\n"); /*** needs to be more elegant */ X exit(1); X } X p->name = "NONAME"; X p->init = badfunc; X p->done = badfunc; X p->line = badfunc; X p->textsize = badfunc; X p->text = badfunc; X p->next = infobase; /* add to list */ X infobase = p; X return p; X} X XPNullSetup() X{ XPDevInfo *p; X p = Pnew(); X p->name = "NULL"; X /* leave other stuff as illegal */ X currentinfo = p; X} X XPSetup() X{ X PNullSetup(); /* set up the non-device */ X /* next, set up each device */ X#ifdef X10 X PXSetup(); X#endif X PHPSetup(); X PTSetup(); X PSZSetup(); X} X X/* end */ END_OF_FILE if test 6831 -ne `wc -c <'plot.c'`; then echo shar: \"'plot.c'\" unpacked with wrong size! fi # end of 'plot.c' fi if test -f 'plot.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plot.h'\" else echo shar: Extracting \"'plot.h'\" \(575 characters\) sed "s/^X//" >'plot.h' <<'END_OF_FILE' X/* plot.h - plot package stuff X * X * 30.Jul.87 jimmc Initial defintion X * 17.Aug.87 jimmc Add textsize function X * 27.Aug.87 jimmc Remove box function X */ X Xtypedef struct _PDevInfo { /* device descriptor */ X struct _PDevInfo *next; /* linked list of device descriptors */ X char *name; X int (*init)(); X int (*done)(); X int (*line)(); X int (*text)(); X int (*textsize)(); X} PDevInfo; X Xextern PDevInfo *Pnew(); X X/* positions for text */ X#define N 0 X#define S 1 X#define E 2 X#define W 3 X#define NE 4 X#define NW 5 X#define SE 6 X#define SW 7 X#define C 8 /* center */ X X/* end */ END_OF_FILE if test 575 -ne `wc -c <'plot.h'`; then echo shar: \"'plot.h'\" unpacked with wrong size! fi # end of 'plot.h' fi if test -f 'plotHP.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plotHP.c'\" else echo shar: Extracting \"'plotHP.c'\" \(7114 characters\) sed "s/^X//" >'plotHP.c' <<'END_OF_FILE' X/* plotHP.c - plot driver for HPGL X * X * 1.Aug.87 jimmc Initial definition X * 17.Aug.87 jimmc Add textsize function X * 19.Aug.87 jimmc Simplify text function X * 20.Aug.87 jimmc Allow selection of size A,B,C,D X * 27.Aug.87 jimmc Remove box function; add size E X * 1.Sep.87 jimmc Add R types (rotated) X * 23.Dec.87 jimmc Add HPPENNUM env var X */ X X#include <stdio.h> X#include "plot.h" X X#define NULL 0 X#define DTCHAR '\003' X Xextern char *index(), *getenv(); X Xextern char *Progname; X Xstatic FILE *PHPfile; Xstatic int PHProtated; Xstatic int PHPxtoy, PHPytox; Xstatic int PenIsDown; Xstatic int CurrentX,CurrentY; X X#define HPGLELEFT (-20320) X#define HPGLERIGHT 20319 X#define HPGLETOP 16255 X#define HPGLEBOTTOM (-16256) X X#define HPGLDLEFT (-16256) X#define HPGLDRIGHT 16255 X#define HPGLDTOP 10159 X#define HPGLDBOTTOM (-10160) X X#define HPGLCLEFT (-10160) X#define HPGLCRIGHT 10159 X#define HPGLCTOP 8127 X#define HPGLCBOTTOM (-8128) X X#define HPGLBLEFT (-8128) X#define HPGLBRIGHT 8127 X#define HPGLBTOP 5079 X#define HPGLBBOTTOM (-5080) X X#define HPGLALEFT (-5080) X#define HPGLARIGHT 5079 X#define HPGLATOP 4063 X#define HPGLABOTTOM (-4064) X Xstatic double PHPTextWidth; Xstatic double PHPTextHeight; Xstatic int PHPFontHeight; X X/* some utility subroutines first */ X Xstatic XpenDown() X{ X if (PenIsDown) return; X fputs("PD;\n", PHPfile); X PenIsDown++; X} X Xstatic XpenUp() X{ X if (!(PenIsDown)) return; X fputs("PU;\n", PHPfile); X PenIsDown = 0; X} X X/* go somewhere but don't worry about the pen */ Xstatic Xto(x,y) Xint x, y; X{ Xint newx, newy; X X if (x==CurrentX && y==CurrentY) return; X CurrentX = x; X CurrentY = y; X if (PHProtated) { X newx = PHPytox-y; X newy = x-PHPxtoy; X x = newx; X y = newy; X } X fprintf(PHPfile, "PA%d,%d;\n", (x), (y)); X} X X/* get to a particular point with the pen up, but don't issue any pen X * commands if we are already there */ Xstatic XtoUp(x,y) Xint x, y; X{ X if (x==CurrentX && y==CurrentY) return; X penUp(); X to(x,y); X} X X/* get to a particular point with the pen down, but don't issue any pen X * commands if we are already there */ Xstatic XtoDown(x,y) Xint x, y; X{ X if (x==CurrentX && y==CurrentY) return; X penDown(); X to(x,y); X} X X/* externally callable routines */ X Xint PHPAInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPxInit(filename,lxp,lyp,hxp,hyp, X HPGLALEFT,HPGLABOTTOM,HPGLARIGHT,HPGLATOP); X} X Xint PHPBInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPxInit(filename,lxp,lyp,hxp,hyp, X HPGLBLEFT,HPGLBBOTTOM,HPGLBRIGHT,HPGLBTOP); X} X Xint PHPCInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPxInit(filename,lxp,lyp,hxp,hyp, X HPGLCLEFT,HPGLCBOTTOM,HPGLCRIGHT,HPGLCTOP); X} X Xint PHPDInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPxInit(filename,lxp,lyp,hxp,hyp, X HPGLDLEFT,HPGLDBOTTOM,HPGLDRIGHT,HPGLDTOP); X} X Xint PHPEInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPxInit(filename,lxp,lyp,hxp,hyp, X HPGLELEFT,HPGLEBOTTOM,HPGLERIGHT,HPGLETOP); X} X Xint PHPARInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPyInit(filename,lxp,lyp,hxp,hyp, X HPGLALEFT,HPGLABOTTOM,HPGLARIGHT,HPGLATOP); X} X Xint PHPBRInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPyInit(filename,lxp,lyp,hxp,hyp, X HPGLBLEFT,HPGLBBOTTOM,HPGLBRIGHT,HPGLBTOP); X} X Xint PHPCRInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPyInit(filename,lxp,lyp,hxp,hyp, X HPGLCLEFT,HPGLCBOTTOM,HPGLCRIGHT,HPGLCTOP); X} X Xint PHPDRInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPyInit(filename,lxp,lyp,hxp,hyp, X HPGLDLEFT,HPGLDBOTTOM,HPGLDRIGHT,HPGLDTOP); X} X Xint PHPERInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X return PHPyInit(filename,lxp,lyp,hxp,hyp, X HPGLELEFT,HPGLEBOTTOM,HPGLERIGHT,HPGLETOP); X} X Xstatic int /* 1 if OK */ XPHPxInit(filename,lxp,lyp,hxp,hyp,left,bottom,right,top) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ Xint left,bottom,right,top; X{ X return PHPnInit(filename,lxp,lyp,hxp,hyp,left,bottom,right,top,0); X} X Xstatic int /* 1 if OK */ XPHPyInit(filename,lxp,lyp,hxp,hyp,left,bottom,right,top) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ Xint left,bottom,right,top; X{ X return PHPnInit(filename,lxp,lyp,hxp,hyp,left,bottom,right,top,1); X} X Xstatic int /* 1 if OK */ XPHPnInit(filename,lxp,lyp,hxp,hyp,left,bottom,right,top,rotated) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ Xint left,bottom,right,top; Xint rotated; X{ Xchar *pn; X X if (strcmp(filename,"stdout")==0) PHPfile=stdout; X else if (strcmp(filename,"stderr")==0) PHPfile=stderr; X else PHPfile = fopen(filename,"w"); X if (!PHPfile) { X printf("can't open file %s",filename); X return 0; X } X fprintf(PHPfile,"IN;PA;\n"); X fprintf(PHPfile,"\033.I;0;17:\n\033.N;19:\n"); /* init handshake */ X fprintf(PHPfile,"IP %d,%d,%d,%d;\n", X left,bottom,right,top); X /* make it square */ X fprintf(PHPfile,"SC %d,%d,%d,%d;\n", X left,right,bottom,top); X fprintf(PHPfile,"PU;PA0,0;\n"); /* go to origin */ X pn = getenv("HPPENNUM"); X if (!pn) pn = "1"; X fprintf(PHPfile,"SP%s;\n",pn); X if (rotated) { X fprintf(PHPfile,"DI0,1;\n"); /* rotate the text */ X PHProtated = 1; X *lxp = bottom; /* x and y sizes are swapped */ X *lyp = left; X *hxp = top; X *hyp = right; X PHPytox = right+left; X PHPxtoy = bottom+top; X } X else { X PHProtated = 0; X *lxp = left; X *lyp = bottom; X *hxp = right; X *hyp = top; X } X return 1; X} X XPHPDone() X{ X fprintf(PHPfile,"IW;PU;SP0;PA0,0;\n"); X fprintf(PHPfile,"NR;\n"); X if (PHPfile!=stdout && PHPfile!=stderr) X fclose(PHPfile); X} X XPHPTextSize(x,y) Xint x,y; X{ X PHPFontHeight = y; X PHPTextHeight = 0.0017 * (double)y; X PHPTextWidth = 0.0017 * (double)x; X fprintf(PHPfile,"SI%g,%g;\n",PHPTextWidth,PHPTextHeight); X /* text size */ X} X XPHPLine(lx,ly,hx,hy) Xint lx,ly,hx,hy; X{ X if (CurrentX==hx && CurrentY==hy) { X toDown(lx,ly); X } X else { X toUp(lx,ly); X toDown(hx,hy); X } X} X XPHPText(x,y,text) Xint x,y; /* lower left corner of text */ Xchar *text; X{ X toUp(x,y); X fprintf(PHPfile,"LB%s%c\n",text,DTCHAR); X} X XPHPSetup() X{ X PHPxSetup("HPA",PHPAInit); X PHPxSetup("HPB",PHPBInit); X PHPxSetup("HPC",PHPCInit); X PHPxSetup("HPD",PHPDInit); X PHPxSetup("HPE",PHPEInit); X PHPxSetup("HPAR",PHPARInit); X PHPxSetup("HPBR",PHPBRInit); X PHPxSetup("HPCR",PHPCRInit); X PHPxSetup("HPDR",PHPDRInit); X PHPxSetup("HPER",PHPERInit); X} X Xstatic XPHPxSetup(name,init) Xchar *name; Xint (*init)(); X{ XPDevInfo *p; X X p = Pnew(); X p->name = name; X p->init = init; X p->done = PHPDone; X p->line = PHPLine; X p->text = PHPText; X p->textsize = PHPTextSize; X} X X/* end */ END_OF_FILE if test 7114 -ne `wc -c <'plotHP.c'`; then echo shar: \"'plotHP.c'\" unpacked with wrong size! fi # end of 'plotHP.c' fi if test -f 'plotSIZE.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plotSIZE.c'\" else echo shar: Extracting \"'plotSIZE.c'\" \(1622 characters\) sed "s/^X//" >'plotSIZE.c' <<'END_OF_FILE' X/* plotSIZE.c - plot driver for finding the size of a plot X * X * 22.Dec.87 jimmc Initial definition X */ X X#include <stdio.h> X#include "plot.h" X Xstatic FILE *PSZfile; Xstatic minx, maxx, miny, maxy; Xstatic int textxsize, textysize; X X#define SIZELEFT 0 X#define SIZERIGHT 1000 X#define SIZEBOTTOM 0 X#define SIZETOP 1000 X Xint /* 1 if OK */ XPSZInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X if (strcmp(filename,"stdout")==0) PSZfile=stdout; X else if (strcmp(filename,"stderr")==0) PSZfile=stderr; X else PSZfile = fopen(filename,"w"); X if (!PSZfile) { X printf("can't open file %s",filename); X return 0; X } X *lxp = maxx = SIZELEFT; X *lyp = maxy = SIZEBOTTOM; X *hxp = minx = SIZERIGHT; X *hyp = miny = SIZETOP; X textxsize = textysize = 0; X return 1; X} X X#define CHECKX(x) { if ((x)<minx) minx=(x); if ((x)>maxx) maxx=(x); } X#define CHECKY(y) { if ((y)<miny) miny=(y); if ((y)>maxy) maxy=(y); } X#define CHECKXY(x,y) CHECKX(x) CHECKY(y) X XPSZDone() X{ X fprintf(PSZfile,"On a scale of 0 to 1000, x=%d and y=%d\n", X maxx-minx, maxy-miny); X if (PSZfile!=stdout && PSZfile!=stderr) X fclose(PSZfile); X} X XPSZTextSize(x,y) Xint x,y; X{ X fprintf(PSZfile,"TextSize (%d %d)\n",x,y); X textxsize = x; X textysize = y; X} X XPSZLine(lx,ly,hx,hy) Xint lx,ly,hx,hy; X{ X CHECKXY(lx,ly) X CHECKXY(hx,hy) X} X XPSZText(x,y,text) Xint x,y; Xchar *text; X{ X CHECKXY(x,y) X CHECKXY(x+strlen(text)*textxsize,y+textysize); X} X XPSZSetup() X{ XPDevInfo *p; X X p = Pnew(); X p->name = "SIZE"; X p->init = PSZInit; X p->done = PSZDone; X p->line = PSZLine; X p->text = PSZText; X p->textsize = PSZTextSize; X} X X/* end */ END_OF_FILE if test 1622 -ne `wc -c <'plotSIZE.c'`; then echo shar: \"'plotSIZE.c'\" unpacked with wrong size! fi # end of 'plotSIZE.c' fi if test -f 'plotTEST.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plotTEST.c'\" else echo shar: Extracting \"'plotTEST.c'\" \(1372 characters\) sed "s/^X//" >'plotTEST.c' <<'END_OF_FILE' X/* plotTEST.c - plot driver for testing X * X * 2.Aug.87 jimmc Initial definition X * 17.Aug.87 jimmc Add textsize function X * 19.Aug.87 jimmc Simplify text function X * 27.Aug.87 jimmc Remove box function X */ X X#include <stdio.h> X#include "plot.h" X Xstatic FILE *PTfile; X X#define TESTLEFT 0 X#define TESTRIGHT 1000 X#define TESTBOTTOM 0 X#define TESTTOP 1000 X Xint /* 1 if OK */ XPTInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X if (strcmp(filename,"stdout")==0) PTfile=stdout; X else if (strcmp(filename,"stderr")==0) PTfile=stderr; X else PTfile = fopen(filename,"w"); X if (!PTfile) { X printf("can't open file %s",filename); X return 0; X } X fprintf(PTfile,"Init %s\n", filename); X *lxp = TESTLEFT; X *lyp = TESTBOTTOM; X *hxp = TESTRIGHT; X *hyp = TESTTOP; X return 1; X} X XPTDone() X{ X fprintf(PTfile,"Done\n"); X if (PTfile!=stdout && PTfile!=stderr) X fclose(PTfile); X} X XPTTextSize(x,y) Xint x,y; X{ X fprintf(PTfile,"TextSize (%d %d)\n",x,y); X} X XPTLine(lx,ly,hx,hy) Xint lx,ly,hx,hy; X{ X fprintf(PTfile,"Line (%d %d)(%d %d)\n",lx,ly,hx,hy); X} X XPTText(x,y,text) Xint x,y; Xchar *text; X{ X fprintf(PTfile,"Text \"%s\" at (%d,%d)\n",text,x,y); X} X XPTSetup() X{ XPDevInfo *p; X X p = Pnew(); X p->name = "TEST"; X p->init = PTInit; X p->done = PTDone; X p->line = PTLine; X p->text = PTText; X p->textsize = PTTextSize; X} X X/* end */ END_OF_FILE if test 1372 -ne `wc -c <'plotTEST.c'`; then echo shar: \"'plotTEST.c'\" unpacked with wrong size! fi # end of 'plotTEST.c' fi if test -f 'plotX.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'plotX.c'\" else echo shar: Extracting \"'plotX.c'\" \(2569 characters\) sed "s/^X//" >'plotX.c' <<'END_OF_FILE' X/* plotX.c - plot routines specific to X X * X * 30.Jul.87 jimmc Initial definition X * 1.Aug.87 jimmc Add PXText, remove PXBox (use default), change PXInit X * 12.Aug.87 jimmc Add XCear in Init X * 17.Aug.87 jimmc Add dummy textsize function X * 19.Aug.87 jimmc Simplify text function X * 26.Jan.88 jimmc Change path to X include files X * 1.Mar.88 jimmc Add ifdef X10 X */ X X#ifdef X10 X X#include <X/Xlib.h> X#include <X/Xproto.h> X#include "plot.h" X X#define NULL 0 X X#define FIXY(y) (y) = (PXwinfo.height-(y)); X Xextern char *index(); X Xextern char *Progname; X Xstatic int PXcolor; Xstatic int PXop; Xstatic int PXplanes; Xstatic Window PXw; Xstatic WindowInfo PXwinfo; Xstatic char *PXFontname = "6x10"; Xstatic FontInfo *PXFontInfo; X X#define PXdefwidth 100 X#define PXdefheight 100 X Xstatic OpaqueFrame PXframe = { X 0, /* window ID */ X 0,0, /* origin */ X 0,0, /* size */ X 1, /* border width */ X 0,0 /* border and background pixmaps */ X}; X Xstatic PXOpenWindow() X{ X PXcolor = 1; X PXop = GXcopy; X PXplanes = AllPlanes; X if (!XOpenDisplay(NULL)) { X printf("Can't open X display\n"); X return 0; X } X PXframe.border = WhitePixmap; X PXframe.background = BlackPixmap; X PXw = XCreate(Progname,Progname,"","=840x600+20+20", X &PXframe,PXdefwidth,PXdefheight); X if (!PXw) { X printf("Can't open window\n"); X return 0; X } X XStoreName(PXw,Progname); X XMapWindow(PXw); X X PXFontInfo = XOpenFont(PXFontname); X if (PXFontInfo==0) { X printf("Can't open font %s",PXFontname); X return 0; X } X X return 1; X} X X/* ARGSUSED */ Xint /* 1 if OK */ XPXInit(filename,lxp,lyp,hxp,hyp) Xchar *filename; /* we ignore this arg */ Xint *lxp,*lyp,*hxp,*hyp; /* returns bounding box of window */ X{ X if (!PXw) { /* need a window */ X if (!PXOpenWindow()) { X return 0; X } X } X XClear(PXw); X XQueryWindow(PXw,&PXwinfo); X *lxp = 0; X *lyp = 0; X *hxp = PXwinfo.width-1; X *hyp = PXwinfo.height-1; X XFlush(); X return 1; X} X XPXDone() X{ X XFlush(); X} X X/* ARGSUSED */ XPXTextSize(x,y) Xint x,y; X{ X return; /*** We are ignoring text size at the moment */ X} X XPXLine(lx,ly,hx,hy) Xint lx,ly,hx,hy; X{ X FIXY(ly) X FIXY(hy) X XLine(PXw,lx,ly,hx,hy,1,1,PXcolor,PXop,PXplanes); X} X XPXText(x,y,text) Xint x,y; /* lower left corner of text */ Xchar *text; X{ X FIXY(y) X y -= PXFontInfo->height; X XTextMaskPad(PXw,x,y,text,strlen(text),PXFontInfo->id, X 0,0,PXcolor,PXop,PXplanes); X} X XPXSetup() X{ XPDevInfo *p; X X p = Pnew(); X p->name = "X"; X p->init = PXInit; X p->done = PXDone; X p->line = PXLine; X p->text = PXText; X p->textsize = PXTextSize; X} X X#else Xstatic char dummy; /* avoid "empty symbol table" message */ X#endif X10 X X/* end */ END_OF_FILE if test 2569 -ne `wc -c <'plotX.c'`; then echo shar: \"'plotX.c'\" unpacked with wrong size! fi # end of 'plotX.c' fi if test -f 'sample.tf' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sample.tf'\" else echo shar: Extracting \"'sample.tf'\" \(3441 characters\) sed "s/^X//" >'sample.tf' <<'END_OF_FILE' Xglobals schema ("textsizex.i" "textsizey.i" "rowposspace.i" "rowdir.s" "trackspace.i" "interrowspace.i" "label.s") Xglobals (6 10 20 "V" 20 30 "") X Xbox schema ("name.s" "sizex.i" "sizey.i" "orgx.i" "orgy.i" X "text.s" "textx.i" "texty.i" "textpos.s") Xconn schema ("boxname.s" "name.s" "x.i" "y.i" "side.s" "netname.s") X Xbox ("I9" 108 50 0 0 "MacMalcolm\n\ X==========\n\ X[9] King Kenneth\n\ X" 6 40 "NW") Xconn ("I9" "i9" 102 13 "E" "i9") Xbox ("I14" 144 50 0 300 "\n\ X[14] Crinan\n\ X of the house of Athol\n\ X" 6 40 "NW") Xconn ("I14" "i14" 72 23 "E" "i14") Xbox ("I19" 78 50 0 600 "\n\ X[19] Sigurd\n\ X d: 1014\n\ X" 6 40 "NW") Xconn ("I19" "i19" 72 23 "E" "i19") Xbox ("F1001" 72 50 0 900 "[1001]\n\ X======\n\ X[4] Lulach\n\ X" 6 40 "NW") Xconn ("F1001" "i3" 0 40 "W" "i3") Xconn ("F1001" "i2" 0 10 "W" "i2") Xconn ("F1001" "i4" 66 13 "E" "i4") Xbox ("F1002" 48 40 0 1200 "[1002]\n\ X======\n\ X" 6 30 "NW") Xconn ("F1002" "i1" 0 30 "W" "i1") Xconn ("F1002" "i2" 0 10 "W" "i2") Xbox ("F1003" 240 60 0 1500 "[1003]\n\ X======\n\ X[1] Macbeth\n\ X bur: Iona (western extremity of Mull)\n\ X" 6 50 "NW") Xconn ("F1003" "i5" 0 50 "W" "i5") Xconn ("F1003" "i1" 72 23 "E" "i1") Xbox ("F1004" 72 50 0 1800 "[1004]\n\ X======\n\ X[5] Finley\n\ X" 6 40 "NW") Xconn ("F1004" "i6" 0 40 "W" "i6") Xconn ("F1004" "i5" 66 13 "E" "i5") Xbox ("F1005" 96 60 0 2100 "[1005]\n\ X======\n\ X[7] Maelbrigdi\n\ X[6] Ruaidhri\n\ X" 6 50 "NW") Xconn ("F1005" "i7" 90 23 "E" "i7") Xconn ("F1005" "i6" 78 13 "E" "i6") Xbox ("F1006" 150 90 0 2400 "[1006]\n\ X======\n\ X[8] Malcolm (Tighernac)\n\ X d: 1029\n\ X[3] Gilcomgain\n\ X d: 1032\n\ X killed\n\ X" 6 80 "NW") Xconn ("F1006" "i7" 0 80 "W" "i7") Xconn ("F1006" "i8" 144 53 "E" "i8") Xconn ("F1006" "i3" 90 33 "E" "i3") Xbox ("F1007" 216 80 0 2700 "[1007]\n\ X======\n\ X[10] Malcolm (Malcolm II)\n\ X d: 1034, Glamis, in Agnus\n\ X Reigned 1005 to 1034; assasinated\n\ X[11] Boete\n\ X" 6 70 "NW") Xconn ("F1007" "i9" 0 70 "W" "i9") Xconn ("F1007" "i10" 156 43 "E" "i10") Xconn ("F1007" "i11" 66 13 "E" "i11") Xbox ("F1008" 72 50 0 3000 "[1008]\n\ X======\n\ X[2] Gruoch\n\ X" 6 40 "NW") Xconn ("F1008" "i11" 0 40 "W" "i11") Xconn ("F1008" "i2" 66 13 "E" "i2") Xbox ("F1009" 84 70 0 3300 "[1009]\n\ X======\n\ X[12] Bethoc\n\ X or Beatrice\n\ X[13] (girl)\n\ X" 6 60 "NW") Xconn ("F1009" "i10" 0 60 "W" "i10") Xconn ("F1009" "i12" 72 33 "E" "i12") Xconn ("F1009" "i13" 72 13 "E" "i13") Xbox ("F1010" 162 70 0 3600 "[1010]\n\ X======\n\ X[15] Duncan\n\ X d: 1039 or 40, Bothgowan\n\ X Slain by Macbeth\n\ X" 6 60 "NW") Xconn ("F1010" "i14" 0 60 "W" "i14") Xconn ("F1010" "i12" 0 10 "W" "i12") Xconn ("F1010" "i15" 72 33 "E" "i15") Xbox ("F1011" 132 50 0 3900 "[1011]\n\ X======\n\ X[17] Malcolm Canmore\n\ X" 6 40 "NW") Xconn ("F1011" "i15" 0 40 "W" "i15") Xconn ("F1011" "i16" 0 10 "W" "i16") Xconn ("F1011" "i17" 126 13 "E" "i17") Xbox ("F1012" 174 70 0 4200 "[1012]\n\ X======\n\ X[18] Siward\n\ X Danish Earl of Northumbria\n\ X[16] (girl)\n\ X" 6 60 "NW") Xconn ("F1012" "i18" 72 33 "E" "i18") Xconn ("F1012" "i16" 72 13 "E" "i16") Xbox ("F1013" 96 60 0 4500 "[1013]\n\ X======\n\ X[23] Thorfinn\n\ X b: about 1009\n\ X" 6 50 "NW") Xconn ("F1013" "i19" 0 50 "W" "i19") Xconn ("F1013" "i13" 0 10 "W" "i13") Xconn ("F1013" "i23" 84 23 "E" "i23") Xbox ("F1014" 96 70 0 4800 "[1014]\n\ X======\n\ X[20] Sumarlidi\n\ X[21] Brusi\n\ X[22] Einar\n\ X" 6 60 "NW") Xconn ("F1014" "i19" 0 60 "W" "i19") Xconn ("F1014" "i20" 90 33 "E" "i20") Xconn ("F1014" "i21" 66 23 "E" "i21") Xconn ("F1014" "i22" 66 13 "E" "i22") END_OF_FILE if test 3441 -ne `wc -c <'sample.tf'`; then echo shar: \"'sample.tf'\" unpacked with wrong size! fi # end of 'sample.tf' fi if test -f 'tfile.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tfile.c'\" else echo shar: Extracting \"'tfile.c'\" \(8931 characters\) sed "s/^X//" >'tfile.c' <<'END_OF_FILE' X/* tfile.c - routines to read a tabular text file X * X * 12.Aug.87 jimmc Initial definition X * 18.Jan.88 jimmc Remove struct defs to tfile.h; lint cleanup X */ X X#include <stdio.h> X#include <varargs.h> X#include <strings.h> X#include "xalloc.h" X#include "tklex.h" X#include "tfile.h" X X#define NIL 0 X Xextern char *index(); X Xstatic struct { X char *name; X int tktype; X} tktypetable[] = { X { "i", TkNumber }, X { "s", TkString }, X}; Xstatic int tktypetablesize = sizeof(tktypetable)/sizeof(tktypetable[0]); X Xstatic XEatToParen(tkhandle) XTkHandle tkhandle; X{ Xint t; X X for (t=TkGet(tkhandle);t!=TkEOF&&t!=TkCParen;t=TkGet(tkhandle)) X ; /* EMPTY - scan until EOF or close paren */ X} X Xstatic XTFsymbol * XFindSymbol(fh,name) XTFstuff *fh; Xchar *name; X{ XTFsymbol *k; X X for (k=fh->symbols;k;k=k->next) { X if (strcmp(name,k->name)==0) return k; X } X return NIL; X} X Xstatic XTFsymbol * XNewSymbol(fh,name) XTFstuff *fh; Xchar *name; X{ XTFsymbol *k; X X k = XCALLOC(TFsymbol,1); X k->next = fh->symbols; X fh->symbols = k; X k->name = XALLOC(char,strlen(name)+1); X strcpy(k->name,name); X return k; X} X Xstatic XAddFieldToSymbol(fh,k,s) XTFstuff *fh; /* in case of errors */ XTFsymbol *k; /* where to add the field name to */ Xchar *s; /* the field name and type to add */ X{ Xchar *st; XTFfiledef *filedef; Xint tktype; XTFprogdef *progdef; XTkHandle tkhandle; Xint n; X X tkhandle = fh->tkhandle; X st = index(s,'.'); /* look for type specifier */ X if (!st) { X fileerror(tkhandle,"no type for field %s",s); X return; X } X *st = 0; /* null terminate the name portion */ X st++; /* point to type itself */ X for (n=0; n<tktypetablesize; n++) { X if (strcmp(st,tktypetable[n].name)==0) break; X } X if (n>=tktypetablesize) { X fileerror(tkhandle,"bad type code %s for symbol %s", X st,s); X/*** abort the scan here? */ X tktype = TkEOF; X } X else tktype=tktypetable[n].tktype; X/*** check for field name conflict */ X filedef = XCALLOC(TFfiledef,1); X if (k->filedeftail) k->filedeftail->next = filedef; X k->filedeftail = filedef; X if (!k->filedef) k->filedef = filedef; X filedef->fieldname = s; X filedef->fieldtype = st; X filedef->tktype = tktype; X/* correlate against progdef info, set up destaddr */ X for (progdef=k->progdef;progdef;progdef=progdef->next) { X if (strcmp(progdef->name,s)==0) break; X } X if (progdef) { /* if we found the name */ X if (progdef->tktype!=filedef->tktype) { X fileerror(tkhandle, X "type mismatch on field %s in table %s", X filedef->fieldname,k->name); X/*** what to do about this error? */ X } X/*** we should really be switching on the tktype here... */ X filedef->destaddr.i = fh->args+progdef->argnum; X } X} X Xstatic XTFScanSchema(fh,s) /* reads a schema definition line from the file */ XTFstuff *fh; Xchar *s; /* name of the file schema to be defined */ X/* The next token to be read is the open paren */ X{ XTkHandle tkhandle; Xint t; XTFsymbol *k; Xchar *sv; X X tkhandle = fh->tkhandle; X k = FindSymbol(fh,s); /* see if a duplicate definition */ X if (k && k->filedef) { X fileerror(tkhandle,"Symbol %s redefined",s); X EatToParen(tkhandle); X return; X } X t = TkGet(tkhandle); X if (t!=TkOParen) { X fileerror(tkhandle,"Expected open paren for schema for %s",s); X EatToParen(tkhandle); X return; X } X if (!k) k = NewSymbol(fh,s); X t = TkGet(tkhandle); X while (t==TkString) { /* read until we come to a close paren */ X sv = TkStringValue(tkhandle); X AddFieldToSymbol(fh,k,sv); X t = TkGet(tkhandle); X } X if (t!=TkCParen) { X fileerror(tkhandle,"Expected string or close parenthesis"); X EatToParen(tkhandle); X } X return; X} X Xstatic XTFScanData(fh,s) /* reads a data line from the file */ XTFstuff *fh; Xchar *s; /* name of the data type to be read */ X/* The open paren has just been read */ X{ XTkHandle tkhandle; XTFsymbol *k; XTFfiledef *f; Xint t; Xint i; X X tkhandle = fh->tkhandle; X k = FindSymbol(fh,s); X if (!k) { X fileerror(tkhandle,"No definition for symbol %s",s); X EatToParen(tkhandle); X return; X } X f = k->filedef; /* point to list of fields */ X for (i=0; i<k->progdefcount; i++) fh->args[i]=0; X t = TkGet(tkhandle); X while (t!=TkCParen && t!=TkEOF) { X if (!f) { X fileerror(tkhandle,"too many fields for type %s",s); X EatToParen(tkhandle); X return; X } X switch (f->tktype) { X case TkNumber: X if (t!=TkNumber) { X fileerror(tkhandle, X "expected integer for field %s", X f->fieldname); X EatToParen(tkhandle); X return; X } X if (f->destaddr.i) X *(f->destaddr.i) = TkNumberValue(tkhandle); X break; X case TkString: X if (t!=TkString) { X fileerror(tkhandle, X "expected string for field %s", X f->fieldname); X EatToParen(tkhandle); X return; X } X if (f->destaddr.s) X *(f->destaddr.s) = TkStringValue(tkhandle); X break; X case TkEOF: /* earlier error */ X break; /* ignore it */ X default: /* should never happen */ X printf("internal error!! line %d, file %s\n",__LINE__, X __FILE__); X break; X } X f = f->next; X t = TkGet(tkhandle); X } X if (f) { X fileerror(tkhandle,"not enough fields"); X return; X } X/* now call the function as requested */ X t = (*k->funcp)(fh->args[0],fh->args[1],fh->args[2], X fh->args[3],fh->args[4],fh->args[5], X fh->args[6],fh->args[7],fh->args[8], X fh->args[9],fh->args[10],fh->args[11]); X/*** what does the return value mean? */ X} X Xstatic Xint /* returns 0 if no more reading to do */ XTFScanOne(fh) /* read one "line" (terminated by close paren) */ XTFstuff *fh; X{ XTkHandle tkhandle; Xint t; Xchar *s,*s2; X X tkhandle = fh->tkhandle; X t = TkGet(tkhandle); X if (t==TkEOF) return 0; /* normal completion */ X if (t==TkOParen) { /* another data item of same type as last */ X if (!fh->lasttype) { X fileerror(tkhandle,"no previous type specified"); X EatToParen(tkhandle); X return 1; X } X TFScanData(fh,fh->lasttype); X return 1; X } X if (t!=TkSymbol) { X fileerror(tkhandle,"Expected start symbol"); X EatToParen(tkhandle); X return 1; X } X s = TkStringValue(tkhandle); /* same symbol value */ X if (fh->lasttype) free(fh->lasttype); X fh->lasttype = s; X t = TkGet(tkhandle); X if (t==TkOParen) { X TFScanData(fh,s); X } X else if (t==TkSymbol) { X s2 = TkStringValue(tkhandle); X if (strcmp(s2,"schema")==0) { X TFScanSchema(fh,s); X } X else { X fileerror(tkhandle, X "Bad keyword '%s' after symbol '%s'",s2,s); X EatToParen(tkhandle); X } X free(s2); X } X else { X fileerror(tkhandle, X "Expected open parenthesis after symbol %s",s); X EatToParen(tkhandle); X } X return 1; /* continue */ X} X Xint /* returns status code (*** what is it?) */ XTFScan(handle) /* top level file scan */ XTFhandle handle; X{ XTFstuff *fh; X X fh = (TFstuff *)handle; X if (!fh) { X printf("No handle for TFScan\n"); X return 0; X } X X while (TFScanOne(fh)) ; /* EMPTY - read until done */ X return 1; /*** what to return? */ X} X X/* VARARGS - really varargs3, but lint doesn't understand va_alist */ XTFSetup(va_alist) X/* args are: handle, name, funcp, args...; null terminates list */ Xva_dcl X{ Xva_list v; XTFhandle handle; Xchar *name; XIFP funcp; /* pointer to func returning int */ XTFstuff *fh; XTFsymbol *k; XTFprogdef *p; Xchar *fd, *fdtype; Xint n; Xint tktype; X X va_start(v); X handle = va_arg(v,TFhandle); X name = va_arg(v,char *); X funcp = va_arg(v,IFP); X fh = (TFstuff *)handle; X if (!fh) { X printf("No handle for TFSetup of %s\n",name); X goto end; /* do va_end and return */ X } X k = FindSymbol(fh,name); X if (k && k->progdef) { X printf("Symbol %s re-setup\n",name); X goto end; /* do va_end and return */ X } X if (!k) k = NewSymbol(fh,name); X k->funcp = funcp; X fd = va_arg(v,char *); /* start looking at field defs */ X while (fd) { X fdtype = index(fd,'.'); X if (!fdtype) { X printf("no type for field %s in setup %s\n", X fd,name); X tktype = TkEOF; X fdtype = fd+strlen(fd)+1; /* for later sub */ X } X else { X fdtype++; X for (n=0; n<tktypetablesize; n++) { X if (strcmp(fdtype,tktypetable[n].name)==0) X break; X } X if (n>=tktypetablesize) { X printf("bad type for field %s in setup %s\n", X fd,name); X tktype = TkEOF; X } X else tktype=tktypetable[n].tktype; X } X/*** eventually we would like to add a constant capability */ X p = XCALLOC(TFprogdef,1); X p->name = XALLOC(char,fdtype-fd); X strncpy(p->name,fd,fdtype-fd-1); X p->name[fdtype-fd-1]=0; X p->tktype = tktype; X if (k->progdeftail) k->progdeftail->next = p; X if (!k->progdef) k->progdef = p; X k->progdeftail = p; X if ((p->argnum=k->progdefcount++) > MAXARGS) { X printf("too many pass-back args for setup %s (max=%d)\n", X name,MAXARGS); X } X fd = va_arg(v,char *); X } Xend: X va_end(v); X} X XTFhandle XTFInit(filename) Xchar *filename; X{ XTFstuff *fh; XTkHandle tkhandle; X X tkhandle = TkInit(filename); X if (!tkhandle) { X printf("can't init file %s\n",filename); X return 0; X } X fh = XCALLOC(TFstuff,1); X fh->tkhandle = tkhandle; X return (TFhandle)fh; X} X XTFDone(handle) XTFhandle handle; X{ XTFstuff *fh; X X fh = (TFstuff *)handle; X if (!fh) { X printf("No handle for TFDone\n"); X } X/*** if anything needs to be freed, do it here */ X if (fh->tkhandle) TkDone(fh->tkhandle); X} X X/* end */ END_OF_FILE if test 8931 -ne `wc -c <'tfile.c'`; then echo shar: \"'tfile.c'\" unpacked with wrong size! fi # end of 'tfile.c' fi if test -f 'tfile.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tfile.h'\" else echo shar: Extracting \"'tfile.h'\" \(1368 characters\) sed "s/^X//" >'tfile.h' <<'END_OF_FILE' X/* tfile.h X * X * 18.Jan.88 jimmc Created by removing from tfile.c X */ X X#define MAXARGS 12 /* max number of args to a setup function */ X Xtypedef int (*IFP)(); X Xtypedef struct _TFfiledef { /* one field as defined in the file */ X struct _TFfiledef *next; X char *fieldname; X char *fieldtype; X int tktype; /* fieldtype expresses as TkXXX */ X union { X int *i; /* where to store if an int */ X char **s; /* where to put pointer if a string */ X } destaddr; /* pointer to where data is to be stored */ X} TFfiledef; X Xtypedef struct _TFprogdef { /* one field as requested in the program */ X struct _TFprogdef *next; X char *name; X int tktype; X int argnum; /* which arg this is to the callback func */ X} TFprogdef; X Xtypedef struct _TFsymbol { /* info about one table */ X struct _TFsymbol *next; /* linked list */ X char *name; /* name of the symbol */ X struct _TFfiledef *filedef; /* head of file field list */ X struct _TFfiledef *filedeftail; X struct _TFprogdef *progdef; /* head of prog field list */ X struct _TFprogdef *progdeftail; X int progdefcount; X IFP funcp; /* the func to call when reading in */ X} TFsymbol; X Xtypedef struct _TFstuff { X TkHandle tkhandle; /* handle to pass to TK routines */ X struct _TFsymbol *symbols; X char *lasttype; X int args[MAXARGS]; X} TFstuff; X Xtypedef TFstuff *TFhandle; X X/* declarations of routines */ Xextern TFhandle TFInit(); X X/* end */ END_OF_FILE if test 1368 -ne `wc -c <'tfile.h'`; then echo shar: \"'tfile.h'\" unpacked with wrong size! fi # end of 'tfile.h' fi if test -f 'tklex.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tklex.h'\" else echo shar: Extracting \"'tklex.h'\" \(2026 characters\) sed "s/^X//" >'tklex.h' <<'END_OF_FILE' X/* tklex.h - defines for tklex package X * X * 27.Jul.87 jimmc Initial definition X * 18.Jan.88 jimmc Move definition of TkInfo into this file from tklex.c X */ X X/* Token types */ X#define TkEOF (-1) X#define TkOParen '(' X#define TkCParen ')' X#define TkString '"' X#define TkNumber '9' X#define TkSymbol 'S' X Xtypedef int (*INTFUNCPTR)(); X Xtypedef struct _TkInfo { X/* All values in this structure are private to the Tk routines; X * the definition is included in this file only to allow the structure X * pointer to be used in the TkHandle typedef. X */ X char *filename; /* name of input file */ X FILE *f; /* input file pointer */ X int lineno; /* input line number (for error messages) */ X int pushedtoken; /* allow one token pushback */ X char *pbchars; /* pushed back characters */ X int pballoc; /* number of bytes allocated in pbchars */ X int pbindex; /* index into pbchars */ X/* If there are no chars pushed back, pbindex==pballoc; each time a char X * is pushed back, pbindex is decremented; each time one is read, it is X * incremented. Thus, the pushback characters in pbchars are stored X * at the end of the pbchars array; printing pbchars[pbindex] will X * print the current push-back string. X * An extra null character is always left on the end (not counted in X * pballoc) so that this can be done (for debugging). X */ X int stringalloc; /* size of stringvalue buffer */ X int stringcount; /* number of chars used (not including null) */ X char *stringvalue; /* where we store the string values */ X/* The stringvalue buffer is used to collect strings which will later X * be returned to the caller. X */ X} TkInfo; X Xtypedef TkInfo *TkHandle; X X/* Routines */ Xextern TkHandle TkInit(); Xextern int TkDone(); Xextern int TkGet(); /* get next token */ Xextern int TkNumberValue(); /* get value of token when TkNumber */ Xextern char *TkStringValue(); /* get value of token when TkString */ Xextern INTFUNCPTR TkSetFatalHandler(); /* set handler for errors */ Xextern INTFUNCPTR TkSetFatalHandler(); /* set handler for errors */ X X/* end */ END_OF_FILE if test 2026 -ne `wc -c <'tklex.h'`; then echo shar: \"'tklex.h'\" unpacked with wrong size! fi # end of 'tklex.h' fi echo shar: End of archive 1 \(of 3\). cp /dev/null ark1isdone MISSING="" for I in 1 2 3 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 3 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.