[comp.sources.unix] v18i015: Tree-structured data placer/router/plotter, Part01/03

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.