From decwrl!wuarchive!cs.utexas.edu!uunet!allbery Fri Nov  3 19:52:59 PST 1989
Article 1147 of comp.sources.misc:
Path: decwrl!wuarchive!cs.utexas.edu!uunet!allbery
From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
Newsgroups: comp.sources.misc
Subject: v08i100: cif2ps: a CIF to PostScript translator
Message-ID: <71226@uunet.UU.NET>
Date: 3 Nov 89 01:25:28 GMT
Sender: allbery@uunet.UU.NET
Reply-To: gwr@gomez.mitre.org (Gordon W. Ross)
Lines: 2787
Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)

Posting-number: Volume 8, Issue 100
Submitted-by: gwr@gomez.mitre.org (Gordon W. Ross)
Archive-name: cif2ps

I've posted my version of "cif2ps" to comp.sources.misc this evening.
Your site should be receiving it soon.  Please accept my apology for
not posting it sooner.  I have been busy, and cif2ps is not a high
priority.  On the brighter side though, I've added support for CIF
objects other than boxes, as well as a limited plot depth option.

Here is the header from the posting to comp.sources.misc:

This package includes the source for "cif2ps," a program to create a
PostScript representation of an integrated circuit from a layout
stored in Caltech Intermediate Form (CIF).  A README, Makefile, and
manual page are included as well as some sample CIF files.

This version was derived from a version distributed by Marc Lesure
of Engineering Computer Services, Arizona State University.
The original version (called "cifp") was written by Arthur Simoneau,
of The Aerospace Corporation, El Segundo, California.

My additions to this program include:
run time customization of plot styles for all CIF layers, limited
plot depth option, technology-independent handling of CIF layers,
PostScript functions for filling an object using a clipping path,
automatic ordering of drawing operations for minimal obliteration,
reduced output size, and support for CIF objects other than boxes.

A few test files are included.  Running "make test" will generate a
layer-key for Scalable CMOS (SCMOS).  The file "everything.cif" has
one object of each CIF type: a box, roundflash, polygon, and wire.
The file "scmos-test.cif" is a sample layout from the old "cifp."

This version of "cif2ps" is distributed without any promise of
support, though I would appreciate bug reports and changes.

Gordon W. Ross    gwr@gomez.mitre.org    (617) 271-3205 (daytime)
The MITRE Corp. (M/S E025)  Burlington Road, Bedford, MA 01730

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	cif2ps.1
#	Makefile
#	psheader.ps
#	define.h
#	cif2ps.c
#	cifgood.c
#	cifplot.c
#	layers.c
#	styles.c
#	layerkey.csh
#	everything.cif
#	scmos-test.cif
# This archive created: Tue Oct 31 17:33:48 1989
# By:	Gordon W. Ross (The MITRE Corporation, Bedford, MA.)
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(4221 characters)'
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
sed 's/^X //' << \SHAR_EOF > 'README'
X This package includes the source for "cif2ps," a program to create a
X PostScript representation of an integrated circuit from a layout
X stored in Caltech Intermediate Form (CIF).  A README, Makefile, and
X manual page are included as well as some sample CIF files.
X 
X This version was derived from a version distributed by Marc Lesure
X of Engineering Computer Services, Arizona State University.
X The original version (called "cifp") was written by Arthur Simoneau,
X of The Aerospace Corporation, El Segundo, California.
X 
X My additions to this program include:
X run time customization of plot styles for all CIF layers, limited
X plot depth option, technology-independent handling of CIF layers,
X PostScript functions for filling an object using a clipping path,
X automatic ordering of drawing operations for minimal obliteration,
X reduced output size, and support for CIF objects other than boxes.
X 
X A few test files are included.  Running "make test" will generate a
X layer-key for Scalable CMOS (SCMOS).  The file "everything.cif" has
X one object of each CIF type: a box, roundflash, polygon, and wire.
X The file "scmos-test.cif" is a sample layout from the old "cifp."
X 
X This version of "cif2ps" is distributed without any promise of
X support, though I would appreciate bug reports and changes.
X 
X Gordon W. Ross    gwr@gomez.mitre.org    (617) 271-3205 (daytime)
X The MITRE Corp. (M/S E025)  Burlington Road, Bedford, MA 01730
X 
X Included below are the contents of README files from older versions.
X ------------------------------------------------------------------
X 
X [ README file from Marc Lesure's version of "cif2ps":  -GWR ]
X 
X This code was originally written by Arthur Simoneau, The Aerospace
X Corporation, El Segundo, California. and was called 'cifp'.  'cifp' would
X only take MAGIC SCMOS cif input and generate postscript for a single
X page of output.
X 
X I've since taken it and modified it to accept cmos-pw technology for
X our local needs at Arizona State University.  The biggest improvement
X I made was to get multiple page output.  Each page is numbered with
X (x,y) coordinates so you know its proper sequence.  Also each page
X overlaps with its neighbor, so you can cut and paste if you want.
X The program will rescale the user-specific scale to avoid producing
X blank pages.  A scaling limit of 5 by 5 has been put in the program to
X eliminate massive outputs.  Cif2ps can generate a postscript file in
X the multi-megabyte range very easily.  I renamed the program to
X 'cif2ps' to be more descriptive of its function.
X 
X Two test files have been included, cmos-pw.test.cif and scmos.test.cif.
X The file cmos-pw.test.cif was generated using the IGS2CIF program
X version 2a.04 on a HP EGS Graphics system.  The file scmos.test.cif is
X from the original 'cifp' distribution.  To plot this file you must use
X the '-T' option on 'cif2ps'.
X 
X [ The "-T" option is no longer needed or available.  -GWR ]
X 
X Cif2ps is now used here in place of cifplot from the Berkeley VSLI
X distribution.
X 
X STANDARD DISCLAIMER:
X -------------------
X The authors and their organizations assume no responsibility for the
X use by the recipient of this program.
X 
X Marc Lesure
X Engineering Computer Services
X Arizona State University
X 
X ---------------------------------------------------------------
X 
X [ README file from Arthur Simoneau's original "cifp":  -GWR ]
X 
X If somebody wants to modify this code you should be aware that the
X order of the "filled boxes" are important.  The last filled box wins
X all of the pixels and so improper order can cause the p-well to
X obliterate all of the CIF geometries.
X 
X [ Filled objects are now handled in a more sophisticated manner. -GWR ]
X 
X I will be maintaining this code and adding missing features as they
X become desirable, so instead of re-inventing the wheel you should
X contact me before making any changes to see if I have already done
X them.  Also, I would like to maintain knowledge of where this code is
X so I would appreciate any new sites request the code from me rather
X than siphoning it from another site.
X 
X I will gladly respond to any bug reports if a suitable example
X displaying the bug is sent to me.
X 
X Cheers,
X Arthur Simoneau
X The Aerospace Corporation
X El Segundo, California
X 
X art@aerospace
X 
X [ I was not able to reach art@aerospace  -GWR ]
SHAR_EOF
if test 4221 -ne "`wc -c < 'README'`"
then
	echo shar: error transmitting "'README'" '(should have been 4221 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'cif2ps.1'" '(5278 characters)'
if test -f 'cif2ps.1'
then
	echo shar: will not over-write existing file "'cif2ps.1'"
else
sed 's/^X //' << \SHAR_EOF > 'cif2ps.1'
X .TH CIF2PS LOCAL "23 June 1989"
X .UC 4
X .SH NAME
X Cif2ps \- CIF to postscript translator
X .SH SYNOPSIS
X .na
X .B cif2ps
X .RB [ \-r ]
X .RB [ \-c
X .IR cell ]
X .RB [ \-d
X .IR depth ]
X .RB [ \-f
X .IR font-size ]
X .RB [ \-w
X .IR width ]
X .RB [ \-h
X .IR height ]
X .RB [ \-s
X .IR LAYER=style-string ]
X .RI [ in-file.cif \ [ out-file.ps ]]
X .ad
X .br
X .SH DESCRIPTION
X .I Cif2ps
X converts a CIF file produced by Magic or another VLSI layout editor
X into PostScript.  The output file produced is complete and suitable
X for printing on a letter-size PostScript printer.
X 
X The first file name (i.e.
X .IR in-file.cif )
X is the input file
X The second file name (i.e.
X .IR out-file.ps )
X is the output file.
X If no file names are given the program reads from standard input
X and writes to standard output.
X If just one file name is specified, it is used as input.
X .PP
X .I Cif2ps
X options are :
X .TP
X .B \-r
X rotate the plot by 90 degrees (cumulative if repeated).
X .TP
X .BI \-c \ cell
X .I cell
X (name or CIF number) should be plotted.
X By default the top-level cell (number zero) is plotted.
X CIF files generated by Magic have a "dummy" top-level cell
X used only for specifying scale factors and the "real" top-level
X cell (as seen in Magic) is number one.
X .TP
X .BI \-d \ depth
X Cells instantiated
X .I depth
X levels or more below the top level should not be plotted.
X The default is zero, meaning plot at all depths.
X A depth of one restricts plotting to the top level.
X .TP
X .BI \-f \ font-size
X Use a font (Helvetica) scaled to a height of
X .I font-size
X points.  The default is 6 points.
X .TP
X .BI \-w \ width
X the plot should be made
X .I width
X pages wide.  By default the width is one page.
X .TP
X .BI \-h \ height
X the plot should be made
X .I height
X pages wide.  By default the height is one page.
X .PP
X .I Cif2ps
X will rescale a user-specific dimension if neccesary to avoid
X producing blank pages.  The largest dimesion allowed is 5 pages by 5 pages
X (25 pages of output).
X .TP
X .BI \-s \ LAYER=style-string
X set the drawing style for the layer named
X .I LAYER
X to the string
X .I style-string.
X Any number of
X .BI \-s \ LAYER=style-string
X pairs of arguments may be given, each defining one CIF layer.
X If
X .I style-string
X is omitted then
X .I LAYER
X is not plotted.
X Built-in default styles are provided for some technologies
X (MOSIS SCMOS and Bulk CMOS, Oct symbolic).
X See
X .B Style Customiztion
X below for information on style strings.
X .SH "Style Customization"
X .PP
X Style strings (used with the
X .B \-s
X option) are simply strings of PostScript commands (with one exception).
X The commands are used to fill each figure generated by
X .I cif2ps.
X The exception is that styles using the printer's built-in
X gray fill function need special handling because this
X fill function uses an opaque fill method (obliterating any
X drawings previously inside the filled area).
X Style strings which use the printer's built-in gray fill do so
X by prepending a special code "G" and a number to the otherwise
X ordinary PostScript string.  The number following the "G"
X is the gray-level to be used, with zero (0) being black and one
X (1.0) being white.  Note that for this special code to be recognized
X the "G" must be the first letter in the style string.
X .PP
X .I Cif2ps
X will write all gray fill boxes in order of decreasing gray-level
X before writing any of the regular PostScript fill styles.
X This produces a plot with most layers being rendered
X with transparent overlap regions.
X .PP
X The PostScript functions provided in addition to gray fill are:
X .TP
X "\fIs a\fR L"
X Fill the region with lines spaced by \fIs\fR pixcels and rotated
X (counter-clockwise) by angle \fIa\fR degrees from horizontal.
X .TP
X "X"
X Draw an "X" across the figure.
X .TP
X "stroke"
X A PostScript primitive which draws a line along the current path
X and then clears the path.  Since the current path is cleared
X by "stroke" it must be used \fIafter\fR any of the above commands.
X .PP
X Some examples:
X .TP
X ""
X (null string) Don't draw anyting for this layer.
X .TP
X "G0"
X Fill with black.
X .TP
X "G.5"
X Fill with 50% gray.
X .TP
X "8 45 L"
X Fill with lines spaced by 8 pixcels and rotated 45 degrees.
X (The lines will have a slope of one.)
X .TP
X "G.75 32 135 L"
X Fill with light gray (75%) and then fill with lines
X spaced by 32 pixcels and rotated by 135 degrees (slope = -1).
X .TP
X "G.5 X stroke"
X Fill with dark gray (50%), draw an "X" from the corners,
X and draw an outline of the figure.
X This produces a box with an diagonals similar to contacts in Magic.
X .SH "SEE ALSO"
X Magic
X .SH AUTHORS
X Arthur Simoneau (of The Aerospace Corporation, El Segundo, Calif)
X wrote the original version, "cifp."
X .br
X Marc Lesure (of Arizona State University, Tempe, AZ)
X modified 'cifp' to produce 'cif2ps',
X adding scale factors and multi-page output.
X .br
X Gordon Ross (of The MITRE Corporation, Bedford, MA)
X added: run-time style customization options,
X transluscent fill operators using PostScript,
X support for CIF polygons, circles, and wires,
X and reduced output file size.
X .SH BUGS
X .PP
X Text is plotted only in the top-most cell chosen for plotting.
X .PP
X The output can (still) become very large.
X Full depth plotting can easily produce output ten times the size of
X the CIF file.  A work-around is to limit the plot depth with the
X .BI \-d \ depth
X option.
X .PP
X Multi-page plots cause repetition of the entire PostScript output for
X each page.  This could be reduced if cif2ps did some clipping.
SHAR_EOF
if test 5278 -ne "`wc -c < 'cif2ps.1'`"
then
	echo shar: error transmitting "'cif2ps.1'" '(should have been 5278 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1045 characters)'
if test -f 'Makefile'
then
	echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X //' << \SHAR_EOF > 'Makefile'
X DEST    = /vlsi/mitre
X CC	= cc -f68881
X CFLAGS	= -O
X LDFLAGS =
X 
X PROGRAM	= cif2ps
X 
X SRCS	= cif2ps.c cifgood.c cifplot.c layers.c styles.c
X OBJS	= cif2ps.o cifgood.o cifplot.o layers.o styles.o psheader.o
X FILES	= README cif2ps.1 Makefile psheader.ps define.h $(SRCS) \
X 	layerkey.csh everything.cif scmos-test.cif
X 
X all:		$(PROGRAM)
X 
X $(PROGRAM): $(OBJS)
X 	$(CC) $(LDFLAGS) -o $@ $(OBJS)
X 
X lint:	$(SRCS)
X 	lint $(SRCS)
X 
X test:	scmos-key.cif
X 	cif2ps scmos-key.cif
X scmos-key.cif:
X 	layerkey.csh CPG CAA CMF CMS \
X 	CWG CWP CWN CSG CSP CSN CCP CCA CVA COG >$@
X 
X dist:	
X 	shar -v -c -b -p "X " $(FILES) >Dist.sha
X 
X .SUFFIXES: .ps
X .ps.c:
X 	( echo "/* This file was generated from $? */" ;\
X 	  echo "char *$*[] = {" ;\
X 	  sed 's/.*/"&",/' <$? ;\
X 	  echo "0 }; /* end of $* */" ) >$@
X .ps.o:
X 	$(MAKE) $(MFLAGS) $*.c
X 	$(CC) $(CFLAGS) -c $*.c
X 	rm -f $*.c
X 
X clean:
X 	rm -f $(OBJS) psheader.c
X 
X install:	$(PROGRAM)
X 	cp -p $(PROGRAM) $(DEST)/bin
X 	cp -p cif2ps.1 $(DEST)/man/man1
X 
X ###
X cif2ps.o:	define.h
X cifgood.o:	define.h
X cifplot.o:	define.h
X layers.o:	define.h
X styles.o:	define.h
SHAR_EOF
if test 1045 -ne "`wc -c < 'Makefile'`"
then
	echo shar: error transmitting "'Makefile'" '(should have been 1045 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'psheader.ps'" '(1843 characters)'
if test -f 'psheader.ps'
then
	echo shar: will not over-write existing file "'psheader.ps'"
else
sed 's/^X //' << \SHAR_EOF > 'psheader.ps'
X % PostScript from \"cif2ps,\" a CIF to PostScript translator by:
X %	Arthur Simoneau, The Aerospace Corporation, El Segundo, Calif
X % with additions by:
X %	Marc Lesure, Arizona State University, Tempe, AZ (May 1988)
X % as well as:
X %	Gordon W. Ross, The MITRE Corporation, Bedford, MA (June 1989)
X %		(proud author of this header code :-)
X 
X % Header code follows:
X 
X /B {	% dx dy x1 y1 ==> ---
X 	% Build a box: size=(dx,dy); lower_left=(x1,y1)
X 	newpath moveto dup 0 exch	% dx dy 0 dy
X 	rlineto exch 0			% dy dx 0
X 	rlineto 0 exch neg		% 0 -dy
X 	rlineto closepath
X } bind def % B
X 
X /L {	% step angle ==> ---
X 	% Fill the current path with lines spaced by STEP and
X 	% rotated from the X-axis by ANGLE degrees ccw.
X 	gsave clip 0 setgray 0 setlinewidth
X 	matrix setmatrix
X 	rotate dup scale		%
X 	pathbbox newpath		% x1 y1 x2 y2
X 	1 add cvi 4 1 roll		% y2' x1 y1 x2
X 	1 add cvi 4 1 roll		% x2' y2' x1 y1
X 	1 sub cvi exch 1 sub cvi	% x2' y2' y1' x1'
X 	2 copy exch translate
X 	3 1 roll sub			% x2' x1' dy
X 	3 1 roll sub exch		% dx dy
X 	{ % repeat (dy) times		% dx
X 		0 0 moveto dup 0	% dx dx 0
X 		rlineto stroke		% dx
X 		0 1 translate		% dx
X 	} repeat pop
X 	grestore
X } bind def % L
X 
X /WW 1 def	% default Wire Width (space from line)
X /Wto {		% x1 y1 x2 y2 ==> x2 y2
X %	Draws a path spaced WW from the line (x1,y1)-(x2,y2)
X newpath
X %	wire angle a=atan(dy/dx)
X 4 2 roll 4 copy	exch		% x2 y2 x1 y1 x2 y2 y1 x1
X 3 1 roll sub 3 1 roll sub	% x2 y2 x1 y1 dy dx
X atan dup 4 1 roll		% x2 y2 a x1 y1 a
X WW exch 90 add dup 180 add arc	% x2 y2 a
X 3 copy pop 3 2 roll		% x2 y2 x2 y2 a
X WW exch 90 sub dup 180 add arc	% x2 y2
X closepath			% x2 y2  (leave for next Wto)
X } bind def % Wto
X 
X /X {	% Draw an X on the current figure
X 	gsave clip
X 	pathbbox newpath	% x1 y1 x2 y2
X 	4 copy moveto lineto	% x1 y1 x2 y2
X 	3 1 roll exch		% x1 y2 x2 y1
X 	moveto lineto stroke	%
X 	grestore
X } bind def % X
X 
X % End of header code
SHAR_EOF
if test 1843 -ne "`wc -c < 'psheader.ps'`"
then
	echo shar: error transmitting "'psheader.ps'" '(should have been 1843 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'define.h'" '(2178 characters)'
if test -f 'define.h'
then
	echo shar: will not over-write existing file "'define.h'"
else
sed 's/^X //' << \SHAR_EOF > 'define.h'
X /*
X  *	Global defines.
X  *	See "cif2ps.c" for authors' names and addresses.
X  *	Please honor the authors by not removing their attributions.
X  */
X 
X #include <stdio.h>
X 
X /* The following dimensions are all in points (1/72 in.) */
X #define PAGEMARGIN	36
X #define PAGEWIDTH	( 8.5 * 72 - 2 * PAGEMARGIN)
X #define PAGELENGTH	(11.0 * 72 - 2 * PAGEMARGIN)
X #define DEFPOINTS	6	/* default points size of text */
X 
X #define BIGINT	0x7FFFFF
X #define false 0
X #define true 1
X 
X #define MAXTOKEN		64
X #define MAXSYMBOLS	256
X #define MAXLINE		1024
X #define LNAMELEN	7
X #define MAXLAYERS	32
X #define MAXNINETY_FOUR	64
X 
X #define DSTYPE		1
X #define BOXTYPE		2
X #define CALLTYPE	3
X #define NINETY_FOURTYPE	4
X #define NGONTYPE	5
X #define ROUNDTYPE	6
X #define WIRETYPE	7
X 
X #define WHITE	' '
X #define COMMA	','
X 
X typedef	struct	{
X 	int	x, y;
X 	}	pointpairtype;
X 
X typedef struct	{
X 	int	layer;
X 	int	llx,lly,urx,ury;
X 	}	boxtype;
X 
X typedef struct	{
X 	int	layer;
X 	int	numPoints;
X 	int	*ptrPoints;
X 	}	ngontype;
X 
X typedef struct	{
X 	int	layer;
X 	int	x,y,r;
X 	}	roundtype;
X 
X typedef struct	{
X 	int	layer;
X 	int	numPoints;
X 	int	*ptrPoints;
X 	int	width;
X 	}	wiretype;
X 
X typedef struct	{
X 	int	name, a, b;
X 	}	dstype;
X 
X typedef struct	{
X 	char	name[MAXNINETY_FOUR];
X 	int	x, y, layer;
X 	}	ninety_fourtype;
X 
X typedef struct	{
X 	int	symbol;
X 	float	matrix[3][3];
X 	}	calltype;
X 
X typedef	struct	symboldumb	{
X 	struct	symboldumb	*next;
X 	int	typer;
X 	union	{
X 		boxtype	*box;
X 		dstype	*ds;
X 		calltype	*call;
X 		ninety_fourtype	*ninety_four;
X 		ngontype	*ngon;
X 		roundtype	*round;
X 		wiretype	*wire;
X 		}	primitive;
X 	}	symboltype;
X 
X typedef	struct	{
X 	int	symbol, a, b;
X 	char	name[MAXTOKEN];
X 	symboltype	*pointer;
X 	pointpairtype	ll, ur;
X 	}	tabletype;
X 
X typedef	struct	{
X     	char	*name;
X 	char	*style;
X 	}	layertype;
X 
X symboltype	*allocsymbol();
X 
X tabletype	symbol_table[MAXSYMBOLS];
X FILE	*ciffile;
X int	no_lines;
X layertype	layers[MAXLAYERS];
X int	order[MAXLAYERS];
X int	layer, numlayers;
X int	last_symbol, current_symbol_index;
X symboltype	*present_symbol;
X char *cur_style;
X float	scale, trans_x, trans_y, a_over_b;
X float	matrix[3][3], top_matrix[3][3];
X int	pagex,pagey;
X int	length,width;
X int	totpages;
X int	font_points;	/* point-size of label font */
X 
X char *psheader[];
X char *style_lookup();
SHAR_EOF
if test 2178 -ne "`wc -c < 'define.h'`"
then
	echo shar: error transmitting "'define.h'" '(should have been 2178 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'cif2ps.c'" '(15796 characters)'
if test -f 'cif2ps.c'
then
	echo shar: will not over-write existing file "'cif2ps.c'"
else
sed 's/^X //' << \SHAR_EOF > 'cif2ps.c'
X /*
X 	cif2ps is based on the program 'cifp' originally written by
X 	Arthur Simoneau, The Aerospace Corporation, El Segundo, Calif
X 
X 	Modified by Marc Lesure, Arizona State University, Tempe, AZ
X 	Changes to 'cifp' include support of cmos-pw layers, scaling
X 	factors to spread output over several pages of 8.5 x 11 paper,
X 	printing multiple layers.
X 
X 	Modified by Gordon W Ross, The MITRE Corporation, Bedford, MA
X 	Designed new PostScript routines to reduce output file size.
X 	Added automatic style selection and run-time customization.
X 	Added rotation option.  (June 1989)
X 
X 	Please honor the authors by not removing their attributions.
X */
X 
X #include <stdio.h>
X extern char *sprintf(); /* missing from stdio.h on Sun! */
X #include <ctype.h>
X #include "define.h"
X 
X int	maxwidth = 5;
X int	maxlength = 5;
X int	depth_lim, depth_now;
X 
X main(argc, argv)
X int	argc;
X char	*argv[];
X 
X {
X 	char *s,*cifname,*plotname,*sym_name;
X 
X 	/* Initialize */
X 	ciffile=stdin;
X 	cifname="(stdin)";
X 	sym_name=0;	/* default (see below) */
X 	depth_lim=0;
X 	length = width = 1;
X 	totpages = 0;
X 	font_points = DEFPOINTS;
X 	no_lines = 0;
X 	layer = 0;
X 	last_symbol = -1;
X 	identity_matrix(top_matrix); /* need for "-r" option */
X 
X 	while (--argc && ++argv && **argv == '-') {
X 		s = argv[0] + 1;
X 		switch (*s) {
X 		case 'c':
X 			sym_name = *++argv;
X 			argc--;
X 			break;
X 
X 		case 'd':
X 			depth_lim = atoi(*++argv);
X 			argc--;
X 			break;
X 
X 		case 'f':
X 			font_points = atoi(*++argv);
X 			argc--;
X 			break;
X 
X 		case 'h':
X 			length = atoi(*++argv);
X 			argc--;
X 			break;
X 
X 		case 'w':
X 			width = atoi(*++argv);
X 			argc--;
X 			break;
X 
X 		case 'r':	/* rotate by 90 degrees */
X 			{
X 				float rotate[3][3];
X 				identity_matrix(rotate);
X 				rotate[0][0] = 0;
X 				rotate[0][1] = -1;
X 				rotate[1][0] = 1;
X 				rotate[1][1] = 0;
X 				hit_matrix(rotate,
X 					   top_matrix,
X 					   top_matrix);
X 			}
X 			break;
X 
X 		case 's':
X 			set_style(*++argv);
X 			argc--;
X 			break;
X 
X 		default:
X 			printf("cif2ps: unknown flag - %s\n",*s);
X 			exit(0);
X 		}
X 	}
X 
X 	if (argc) {	/* input file name supplied? */
X 	    cifname = *argv++; argc--;
X 	    if (!freopen(cifname, "r", stdin)) {
X 		fprintf(stderr, "%s: can't read\n", cifname);
X 		exit(1);
X 	    }
X 	}
X 
X 	if (argc) {	/* output file name supplied? */
X 	    plotname = *argv++; argc--;
X 	    if (!freopen(plotname, "w", stdout)) {
X 		fprintf(stderr, "%s: can't write\n", plotname);
X 		exit(1);
X 	    }
X 	}
X 
X 	if (argc) {	/* extra args must be errors */
X 		fprintf(stderr,
X 	"Usage: cif2ps [-w width] [-h height] [input [output]]\n");
X 		exit(0);
X 	}
X 
X 	if (width <= 0) {
X 		printf("-w exceeds lower limit - setting to 1\n");
X 		width = 1;
X 	}
X 	if (length <= 0) {
X 		printf("-l exceeds lower limit - setting to 1\n");
X 		length = 1;
X 	}
X 	if (width > maxwidth) {
X 		printf("-w exceeds upper limit - setting to %d\n",maxwidth);
X 		width = maxwidth;
X 	}
X 	if (length > maxlength) {
X 		printf("-l exceeds upper limit - setting to %d\n",maxlength);
X 		length = maxlength;
X 	}
X 
X 	copy_matrix(top_matrix, matrix);
X 	ds("DS 0", DSTYPE); /* cell 0 is predefined. Yech! -GWR */
X 	nine("9 top_level");
X 	do_cif();	/* parse input */
X 	style_sort();	/* determine plot order for layers */
X 	plot_symbol(sym_name);
X }	/*main*/
X 
X 
X 
X plot_symbol(sym_name)
X char	*sym_name;
X {
X 	pointpairtype	ll, ur;
X 	int	sym_index = 0;
X 
X 	/* get the symbol number */
X 	if (sym_name) {
X 		if (isdigit(*sym_name)) {
X 			sym_index = get_index(atoi(sym_name));
X 		} else {
X 			sym_index = sym_lookup(sym_name);
X 		}
X 		if (sym_index < 0) {
X 			fprintf(stderr,
X 				"%s: symbol not found\n",
X 				sym_name);
X 			output_all_symbolnums(stderr);
X 			exit(1);
X 		}
X 	} else {
X 		/* use default choice of symbol */
X 		/* usually want "1" if it exists, else "0" */
X 		sym_index = get_index(1);
X 		if (sym_index < 0) sym_index = 0;
X 	}
X 
X 	ll.x = BIGINT;
X 	ur.x = -BIGINT;
X 	ll.y = BIGINT;
X 	ur.y = -BIGINT;
X 	
X 	get_bounds(sym_index, &ll, &ur);
X 	if ((ll.x == BIGINT) || (ll.y == BIGINT)) {
X 		fprintf(stderr, "cell number %s is empty\n",
X 			sym_name);
X 		exit(1);
X 	}
X 	get_pair(ll.x, ll.y, &ll);
X 	get_pair(ur.x, ur.y, &ur);
X 	fix_bbox(&ll, &ur); /* transformed? */
X 	
X 	get_window(&ll, &ur);
X 	init_cif();
X 	putHeader();
X 	
X 	for(pagey=0; pagey < length; pagey++) {
X 		for(pagex=0; pagex < width; pagex++) {
X 			startPage();
X 			plot_boxes(symbol_table[sym_index].pointer);
X 			plot_textes(symbol_table[sym_index].pointer);
X 			finishPage();
X 		}
X 	}
X 	putTrailer();
X }	/*plotcif*/
X 
X 
X int
X sym_lookup(sym_name)	/* return symbol table index */
X char	*sym_name;
X {
X 	int	i;
X 
X 	for(i = 0; i <= last_symbol; i++) {
X 		if (symbol_table[i].name &&
X 		    !strcmp(symbol_table[i].name, sym_name))
X 			return(i);
X 	}
X 	return(-1);
X }
X 
X 
X get_window(ll, ur)
X pointpairtype	*ll, *ur;
X {
X 	/* assigns global variables: scale, trans_x, trans_y */
X 	/* Note: scale maps from CIF coordinates to 72'nds of inches */
X 
X 	float	scalex, scaley;
X 	float   deltax, deltay;
X 	int	newsize;
X 
X 	trans_x = - ll->x;
X 	trans_y = - ll->y;
X 
X 	deltax = ur->x - ll->x;
X 	scalex = width * PAGEWIDTH / deltax;
X 
X 	deltay = ur->y - ll->y;
X 	scaley = length * PAGELENGTH / deltay;
X 
X 	if (scalex < scaley) {
X 		scale = scalex;
X 		newsize = ((deltay * scale) / PAGELENGTH) + 1;
X 		if (newsize != length) {
X 			printf("output length changed from %d to %d\n",
X 				length, newsize);
X 			length = newsize;
X 		}
X 	} else {
X 		scale = scaley; 
X 		newsize = ((deltax * scale) / PAGEWIDTH) + 1;
X 		if (newsize != width) {
X 			printf("output width changed from %d to %d\n",
X 				newsize,length);
X 			width = newsize;
X 		}
X 	}
X }	/*get_window*/
X 
X 
X plot_boxes(symbol)
X symboltype	*symbol;
X {
X 	int i;
X 
X 	/* first we plot all the opaque (gray fill) styles */
X 	for (i=0; i<numlayers; i++) {
X 		layer = order[i];
X 		if (style_gray(layers[layer].style)) {
X 			printf("%% %s\n", layers[layer].name);
X 			depth_now = 0;
X 			plot_boxes_sub(symbol);
X 		}
X 	}
X 	puts("0 setgray");
X 	/* plot the remaining styles (any order is fine) */
X 	for (i = 0; i < numlayers; i++) {
X 		layer = i;
X 		if (style_rest(layers[layer].style)) {
X 			printf("%% %s\n", layers[layer].name);
X 			depth_now = 0;
X 			plot_boxes_sub(symbol);
X 		}
X 	}
X }	/*plot_boxes*/
X 
X 
X plot_boxes_sub(symbol)
X symboltype	*symbol;
X {
X float	temp_matrix[3][3];
X 
X 	while(symbol != NULL)
X 		{
X 		switch(symbol->typer)
X 			{
X 		case BOXTYPE:
X 			plot_box(symbol->primitive.box);
X 			break;
X 		case NGONTYPE:
X 			plot_ngon(symbol->primitive.ngon);
X 			break;
X 		case ROUNDTYPE:
X 			plot_round(symbol->primitive.round);
X 			break;
X 		case WIRETYPE:
X 			plot_wire(symbol->primitive.wire);
X 			break;
X 		case CALLTYPE:
X 			/* if at depth_lim, skip calls */
X 			if (depth_lim &&
X 			    (depth_lim <= (depth_now + 1)))
X 				break;
X 			depth_now++;
X 			copy_matrix(matrix, temp_matrix);
X 			hit_matrix(matrix,
X 				symbol->primitive.call->matrix,
X 				matrix);
X 			plot_boxes_sub(
X 		symbol_table[symbol->primitive.call->symbol].pointer);
X 			copy_matrix(temp_matrix, matrix);
X 			depth_now--;
X 			break;
X 		case DSTYPE:
X 		case NINETY_FOURTYPE:
X 			break;
X 		default:
X 			fprintf(stderr, "ERROR Not known %d in plot boxes\n",
X 							symbol->typer);
X 			break;
X 			}
X 
X 		symbol = symbol->next;
X 		}
X 
X 	return;
X }	/*plot_boxes_sub*/
X 
X 
X 
X plot_textes(symbol)
X symboltype	*symbol;
X 
X {
X ninety_fourtype		*ninety_four;
X 
X 	puts("0 setgray");
X 	while(symbol != NULL)
X 		{
X 		switch(symbol->typer)
X 			{
X 		case CALLTYPE:	/* only plots text in top level */
X 		case DSTYPE:
X 		case BOXTYPE:
X 		case NGONTYPE:
X 		case ROUNDTYPE:
X 		case WIRETYPE:
X 			break;
X 		case NINETY_FOURTYPE:
X 			ninety_four = symbol->primitive.ninety_four;
X 			plot_text(ninety_four);
X 			break;
X 		default:
X 			fprintf(stderr, "ERROR unknown %d in plot_textes\n",
X 							symbol->typer);
X 			break;
X 			}
X 
X 		symbol = symbol->next;
X 		}
X }	/*plot_textes*/
X 
X 
X 
X bound_point(ll,ur,x,y)
X pointpairtype	*ll, *ur;
X int x,y;
X {
X 	if (ll->x > x) ll->x = x;
X 	if (ll->y > y) ll->y = y;
X 	if (ur->x < x) ur->x = x;
X 	if (ur->y < y) ur->y = y;
X }
X 
X bound_box(ll,ur,box)
X pointpairtype	*ll, *ur;
X boxtype *box;
X {
X 	bound_point(ll,ur,box->llx,box->lly);
X 	bound_point(ll,ur,box->urx,box->ury);
X }
X 
X bound_ngon(ll,ur,ngon)
X pointpairtype	*ll, *ur;
X ngontype *ngon;
X {
X 	int n = ngon->numPoints;
X 	int *a = ngon->ptrPoints;
X 	do {
X 		bound_point(ll,ur,a[0],a[1]);
X 		n--; a += 2;
X 	} while (n);
X }
X 
X bound_round(ll,ur,round)
X pointpairtype	*ll, *ur;
X roundtype *round;
X {
X 	bound_point(ll,ur,
X 		    round->x - round->r,
X 		    round->y - round->r);
X 	bound_point(ll,ur,
X 		    round->x + round->r,
X 		    round->y + round->r);
X }
X 
X bound_wire(ll,ur,wire)
X pointpairtype	*ll, *ur;
X wiretype *wire;
X {
X 	int n = wire->numPoints;
X 	int *a = wire->ptrPoints;
X 	do {
X 		bound_point(ll,ur,a[0],a[1]);
X 		n--; a += 2;
X 	} while (n);
X 	ll->x -= wire->width;
X 	ll->y -= wire->width;
X 	ur->x += wire->width;
X 	ur->y += wire->width;
X }
X 
X 
X 
X get_bounds(sym, ll, ur)
X int	sym;
X pointpairtype	*ll, *ur;
X 
X {
X int		local_sym;
X symboltype	*symbol;
X pointpairtype	local_ll, local_ur;
X float	temp_matrix[3][3];
X 
X 	symbol = symbol_table[sym].pointer;
X 	while(symbol != NULL)
X 		{
X 		switch(symbol->typer)
X 			{
X 		case DSTYPE:
X 		case NINETY_FOURTYPE:
X 			break;
X 		case BOXTYPE:
X 			bound_box(ll,ur,symbol->primitive.box);
X 			break;
X 		case NGONTYPE:
X 			bound_ngon(ll,ur,symbol->primitive.ngon);
X 			break;
X 		case ROUNDTYPE:
X 			bound_round(ll,ur,symbol->primitive.round);
X 			break;
X 		case WIRETYPE:
X 			bound_wire(ll,ur,symbol->primitive.wire);
X 			break;
X 		case CALLTYPE:
X 			local_sym = symbol->primitive.call->symbol;
X 			if (symbol_table[local_sym].ll.x == BIGINT)
X 				{
X 				get_bounds(local_sym,
X 					&(symbol_table[local_sym].ll),
X 					&(symbol_table[local_sym].ur));
X 				}
X 			copy_matrix(matrix, temp_matrix);
X 			copy_matrix(symbol->primitive.call->matrix, matrix);
X 			get_pair(symbol_table[local_sym].ll.x,
X 				symbol_table[local_sym].ll.y, &local_ll);
X 			get_pair(symbol_table[local_sym].ur.x,
X 				symbol_table[local_sym].ur.y, &local_ur);
X 			copy_matrix(temp_matrix, matrix);
X 
X 			/* local_ll and local_ur may be transformed
X 			 * such that left>right or lower>upper ...
X 			 */
X 			fix_bbox(&local_ll, &local_ur);
X 			if (ll->x > local_ll.x)
X 			    ll->x = local_ll.x;
X 			if (ll->y > local_ll.y)
X 			    ll->y = local_ll.y;
X 			if (ur->x < local_ur.x)
X 			    ur->x = local_ur.x;
X 			if (ur->y < local_ur.y)
X 			    ur->y = local_ur.y;
X 			break;
X 
X 		default:
X 			fprintf(stderr, "ERROR Not known %d in get_bounds\n",
X 							symbol->typer);
X 			break;
X 			}
X 
X 		symbol = symbol->next;
X 		}
X }	/*get_bounds*/
X 
X 
X get_pair(x, y, pair)
X int	x, y;
X pointpairtype	*pair;
X 
X {
X 	pair->x = (x * matrix[0][0]) + (y * matrix[0][1]) + matrix[0][2];
X 	pair->y = (x * matrix[1][0]) + (y * matrix[1][1]) + matrix[1][2];
X }	/*get_pair*/
X 
X 
X 
X call_symbol(cif)
X char	*cif;
X 
X {
X int	last_read, callnum;
X char	token[MAXTOKEN];
X char	ciftemp[MAXLINE];
X int	rotate_x, rotate_y;
X float	multi_matrix[3][3];
X float	temp_a_over_b, translate_x, translate_y;
X calltype	*call, *alloccall();
X 
X 	bang_symbol();
X 	present_symbol->typer = CALLTYPE;
X 	call = alloccall();
X 	present_symbol->primitive.call = call;
X 
X 	last_read = get_token(cif, 2, token);
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "no symbol in CALL\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 	(void) sscanf(token, "%d", &callnum);
X 	call->symbol = get_index(callnum);
X 	if (call->symbol == -1)
X 		{
X 		sprintf(ciftemp, "DS %d", callnum);
X 		temp_a_over_b = a_over_b;
X 		ds(ciftemp, CALLTYPE);
X 		a_over_b = temp_a_over_b;
X 
X 		call->symbol = get_index(callnum);
X 		if (call->symbol == -1)
X 			{
X 			fprintf(stderr, "Error in call cif\n");
X 			cif_output(stderr, cif);
X 			}
X 		}
X 
X 	identity_matrix(multi_matrix);
X 	while(1) {
X 		last_read = get_token(cif, last_read, token);
X 		if (last_read == -1) break;
X 
X 		if (token[0] == 'M')
X 			{
X 			switch(token[1])
X 				{
X 			case 'X':
X 				multi_matrix[0][0] = -1;
X 				hit_matrix(multi_matrix,
X 					   call->matrix,
X 					   call->matrix);
X 				multi_matrix[0][0] = 1;
X 				break;
X 			case 'Y':
X 				multi_matrix[1][1] = -1;
X 				hit_matrix(multi_matrix,
X 					   call->matrix,
X 					   call->matrix);
X 				multi_matrix[1][1] = 1;
X 				break;
X 			default:
X 				fprintf(stderr,
X 					"Error in mirror %c\n",
X 					token[1]);
X 				cif_output(stderr, cif);
X 				break;
X 				}	/*switch mirror*/
X 			}	/*if mirror*/
X 		else if (token[0] == 'R')
X 			{
X 			last_read = get_token(cif, last_read, token);
X 			if (last_read == -1)
X 				{
X 				fprintf(stderr, "error in rotate\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}
X 			(void) sscanf(token, "%d", &rotate_x);
X 			rotate_x = sign(rotate_x);
X 			last_read = get_token(cif, last_read, token);
X 			if (last_read == -1)
X 				{
X 				fprintf(stderr, "error2 in rotate\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}
X 			(void) sscanf(token, "%d", &rotate_y);
X 			rotate_y = sign(rotate_y);
X 			switch(rotate_x)
X 				{
X 			case 1:
X 				if (rotate_y != 0)
X 					fprintf(stderr,
X 						"Bad rotation x %d y %d\n",
X 						rotate_x, rotate_y);
X 				break;
X 			case -1:
X 				if (rotate_y != 0)
X 					{
X 					fprintf(stderr,
X 						"Bad rotation x %d y %d\n",
X 						rotate_x, rotate_y);
X 					break;
X 					}
X 				multi_matrix[0][0] = -1;
X 				multi_matrix[1][1] = -1;
X 				hit_matrix(multi_matrix,
X 					   call->matrix,
X 					   call->matrix);
X 				identity_matrix(multi_matrix);
X 				break;
X 			case 0:
X 				switch(rotate_y)
X 					{
X 				case 1:
X 					multi_matrix[0][0] = 0;
X 					multi_matrix[1][1] = 0;
X 					multi_matrix[0][1] = -1;
X 					multi_matrix[1][0] = 1;
X 					hit_matrix(multi_matrix,
X 						   call->matrix,
X 						   call->matrix);
X 					identity_matrix(multi_matrix);
X 					break;
X 				case -1:
X 					multi_matrix[0][0] = 0;
X 					multi_matrix[1][1] = 0;
X 					multi_matrix[0][1] = 1;
X 					multi_matrix[1][0] = -1;
X 					hit_matrix(multi_matrix,
X 						   call->matrix,
X 						   call->matrix);
X 					identity_matrix(multi_matrix);
X 					break;
X 				default:
X 					fprintf(stderr,
X 						"Bad rotation x %d y %d\n",
X 						rotate_x, rotate_y);
X 					break;
X 					}	/*switch y*/
X 				break;
X 			default:
X 				fprintf(stderr, "Bad rotation x %d y %d\n",
X 					rotate_x, rotate_y);
X 				break;
X 				}	/*switch rotation*/
X 			}	/*if rotate*/
X 		else if (token[0] == 'T')
X 			{
X 			last_read = get_token(cif, last_read, token);
X 			if (last_read == -1)
X 				{
X 				fprintf(stderr, "error in translate\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}
X 			(void) sscanf(token, "%f", &translate_x);
X 			translate_x *= a_over_b;
X 
X 			last_read = get_token(cif, last_read, token);
X 			if (last_read == -1)
X 				{
X 				fprintf(stderr, "error2 in translate\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}
X 			(void) sscanf(token, "%f", &translate_y);
X 			translate_y *= a_over_b;
X 
X 			if ((translate_x != 0) || (translate_y != 0))
X 				{
X 				multi_matrix[0][2] = translate_x;
X 				multi_matrix[1][2] = translate_y;
X 				hit_matrix(multi_matrix,
X 					   call->matrix,
X 					   call->matrix);
X 				identity_matrix(multi_matrix);
X 				}
X 			}	/*if translate*/
X 		else
X 			{
X 			fprintf(stderr, "error---out of calls\n");
X 			cif_output(stderr, cif);
X 			fprintf(stderr, "\ttoken %s\n", token);
X 			break;
X 			}
X 		}	/* while(1) */
X }	/*call_symbol*/
X 
X sign(x)
X int x;
X {
X 	int z;
X 
X 	z = 0;
X 	if (x > 0) z = 1;
X 	if (x < 0) z = -1;
X 	return(z);
X }
X 
X 
X identity_matrix(matrix)
X float	matrix[3][3];
X 
X {
X 	matrix[0][0] = 1;
X 	matrix[0][1] = 0;
X 	matrix[0][2] = 0;
X 	matrix[1][0] = 0;
X 	matrix[1][1] = 1;
X 	matrix[1][2] = 0;
X 	matrix[2][0] = 0;
X 	matrix[2][1] = 0;
X 	matrix[2][2] = 1;
X }	/*identity_matrix*/
X 
X 
X 
X hit_matrix(left_matrix, right_matrix, to_matrix)
X float	left_matrix[3][3], right_matrix[3][3], to_matrix[3][3];
X 
X {
X int	i, j;
X float	temp[3][3];
X 
X 	for(i = 0; i < 3; i++)
X 		for(j = 0; j < 3; j++)
X 			temp[i][j] = left_matrix[i][0] * right_matrix[0][j]
X 			           + left_matrix[i][1] * right_matrix[1][j]
X 				   + left_matrix[i][2] * right_matrix[2][j];
X 	copy_matrix(temp, to_matrix);
X }	/*hit_matrix*/
X 
X 
X copy_matrix(from_matrix, to_matrix)
X float	from_matrix[3][3], to_matrix[3][3];
X 
X {
X int	i, j;
X 
X 	for(i = 0; i < 3; i++)
X 		{
X 		for(j = 0; j < 3; j++)
X 			to_matrix[i][j] = from_matrix[i][j];
X 		}
X }	/*copy_matrix*/
X 
X 
X fix_bbox(ll, ur)
X pointpairtype *ll, *ur;
X {
X 	float temp;
X 	if (ll->x > ur->x) {	/* swap */
X 		temp = ll->x;
X 		ll->x = ur->x;
X 		ur->x = temp;
X 	}
X 	if (ll->y > ur->y) {	/* swap */
X 		temp = ll->y;
X 		ll->y = ur->y;
X 		ur->y = temp;
X 	}
X }
SHAR_EOF
if test 15796 -ne "`wc -c < 'cif2ps.c'`"
then
	echo shar: error transmitting "'cif2ps.c'" '(should have been 15796 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'cifgood.c'" '(13422 characters)'
if test -f 'cifgood.c'
then
	echo shar: will not over-write existing file "'cifgood.c'"
else
sed 's/^X //' << \SHAR_EOF > 'cifgood.c'
X /*
X  *	CIF parser code.
X  *	See "cif2ps.c" for authors' names and addresses.
X  *	Please honor the authors by not removing their attributions.
X  */
X 
X #include "define.h"
X #include <malloc.h>
X 
X #define DELTA_A	'a' - 'A'
X 
X init_cif()
X {
X 	layer = 0;
X }	/*init_cif*/
X 
X 
X get_next_cifline(stringer)
X char	*stringer;
X 
X {
X 	int	i;
X 	int	c;
X 
X 	for(i = 0; i < MAXLINE; i++) {
X 		c = getchar();
X 		if (c == ';') {
X 			stringer[i] = '\0';
X 			return(i);
X 			}
X 		else if (c == '\n')
X 			{
X 			stringer[i] = ' ';
X 			no_lines++;
X 			}
X 		else if (c == EOF)
X 			{
X 			stringer[i] = '\0';
X 			if (i) return(i);
X 			return(EOF);
X 			}
X 		else if (c == '(')
X 			{
X 			while (getchar() != ')') ;
X 			}
X 		else
X 			stringer[i] = c;
X 
X 	} /* for (i ...) */
X 
X 	fprintf(stderr, "Cifline exceeded bounds\n");
X 	stringer[i] = '\0';
X 	cif_output(stderr, stringer);
X 	exit(1);
X 	/*NOTREACHED*/
X }	/*get_next_cifline*/
X 
X 
X 
X cif_output(filer, cif)
X FILE	*filer;
X char	*cif;
X 
X {
X 	fprintf(filer, "%s\t\t(*near line %d*)\n", cif, no_lines);
X }	/*cif_output*/
X 
X 
X trim_cif(cif)
X char	*cif;
X 
X {
X int	i, j, toggle_white;
X 
X 	i = 0;
X 	j = 0;
X 	toggle_white = 1;		/*so no white at beginning*/
X 	for (i = 0; i < MAXLINE; i++)
X 		{
X 		if (cif[i] == COMMA)
X 			{
X 				cif[i] = WHITE;
X 			}
X 		if (cif[i] == '\0')
X 			{
X 			cif[j] = '\0';
X 			return;
X 			}
X 		else if (white(cif[i]))
X 			{
X 			if ( !toggle_white)	/*makes one white space*/
X 				{
X 				cif[j++] = ' ';
X 				toggle_white = 1;
X 				}
X 			}
X 		else
X 			{
X 			cif[j++] = cif[i];
X 			if (toggle_white) toggle_white = 0;
X 			}
X 		}	/*for*/
X }	/*trim_cif*/
X 
X 
X white(chr)
X char	chr;
X 
X {
X 	switch(chr)
X 		{
X 	case ' ':
X 	case '\t':
X 		return(1);
X 	default:
X 		return(0);
X 		}
X }	/*white*/
X 
X 
X 
X symboltype
X *allocsymbol()
X {
X unsigned	size = sizeof(symboltype);
X symboltype	*symbol;
X 
X 	symbol =(symboltype *) malloc(size);
X 	symbol->typer = 0;
X 	symbol->primitive.box = NULL;
X 	symbol->next = NULL;
X 
X 	return(symbol);
X }	/*allocsymbol*/
X 
X 
X 	boxtype
X *allocbox()
X {
X 	unsigned	size = sizeof(boxtype);
X 	boxtype	*box;
X 	box = (boxtype *) malloc(size);
X 	return(box);
X }	/*allocbox*/
X 
X 
X 
X int
X get_index(num)
X int	num;
X {
X 	int	i;
X 
X 	for(i = 0; i <= last_symbol; i++)
X 		{
X 		if (symbol_table[i].symbol == num) return(i);
X 		}
X 
X 	return(-1);
X }	/*get_index*/
X 
X 
X 
X output_all_symbolnums(filer)
X FILE	*filer;
X 
X {
X int	i;
X 
X 	fprintf(filer, "Symbols are:\n");
X 	for(i = 0; i <= last_symbol; i++)
X 		fprintf(filer, "%d\t%s\n", symbol_table[i].symbol,
X 							symbol_table[i].name);
X }	/*output_all_symbolnums*/
X 
X 
X 
X do_cif()
X {
X char	cif[MAXLINE];
X 
X 	while (get_next_cifline(cif) != EOF) {
X 
X 		trim_cif(cif);
X 
X 		switch(cif[0]) {
X 		case 'D':
X 			switch(cif[1])
X 				{
X 			   case 'S':
X 				ds(cif, DSTYPE);
X 				break;
X 			   case 'F':
X 				df();
X 				break;
X 			   default:
X 				fprintf(stderr, "Unknown command in CIF\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}	/*switch(cif[1]*/
X 			break;
X 		case '9':
X 			switch(cif[1])
X 				{
X 			   case WHITE:
X 				nine(cif);
X 				break;
X 			   case '4':
X 				ninety_four(cif);
X 				break;
X 			   default:
X 				fprintf(stderr, "Unknown command in CIF\n");
X 				cif_output(stderr, cif);
X 				break;
X 				}	/*switchcif[1]*/
X 			break;
X 		case 'B':
X 			cif_box(cif);
X 			break;
X 		case 'C':
X 			call_symbol(cif);
X 			break;
X 		case 'L':
X 			cif_change_layer(cif);
X 			break;
X 		case 'P':
X 			cif_polygon(cif);
X 			break;
X 		case 'R':
X 			cif_round(cif);
X 			break;
X 		case 'W':
X 			cif_wire(cif);
X 			break;
X 		case 0:
X 			break;
X 		case 'E':
X 			return;
X 
X 		default:
X 			fprintf(stderr, "Syntax error:\n");
X 			cif_output(stderr, cif);
X 			break;
X 		}	/*switch*/
X 	} /* while (get_next_cifline(cif)...) */
X 	fprintf(stderr, "Premature end of file\n");
X }	/*do_cif*/
X 
X 
X ds(cif, typer)
X char	*cif;
X int	typer;
X 
X {
X int	last_read, symnum, temp_index;
X char	token[MAXTOKEN];
X symboltype	*symbol;
X 
X 	last_read = get_token(cif, 2, token); /* space optional */
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "no symbol in DS\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 	(void) sscanf(token, "%d", &symnum);
X 
X 	temp_index = get_index(symnum);
X 	if (temp_index == -1)
X 		{
X 		if (++last_symbol == MAXSYMBOLS)
X 			{
X 			fprintf(stderr, "Exceeded the number of allowed symbols\n");
X 			exit(1);
X 			}
X 		temp_index = last_symbol;
X 		}
X 
X 	symbol_table[temp_index].symbol = symnum;
X 	symbol_table[temp_index].ll.x = BIGINT;
X 	symbol_table[temp_index].ll.y = BIGINT;
X 	symbol_table[temp_index].ur.x = -BIGINT;
X 	symbol_table[temp_index].ur.y = -BIGINT;
X 	symbol_table[temp_index].name[0] = '\0';
X 	symbol_table[temp_index].a = 1;
X 	symbol_table[temp_index].b = 1;
X 	a_over_b = 1;
X 
X 	symbol = allocsymbol();
X 	if (typer == DSTYPE)
X 		{
X 		current_symbol_index = temp_index;
X 		present_symbol = symbol;
X 		}
X 	symbol->typer = DSTYPE;
X 
X 	symbol_table[temp_index].pointer = symbol;
X 	*symbol_table[temp_index].name = '\0';
X 
X 	last_read = get_token(cif, last_read, token);
X 	if (last_read == -1) return;
X 	(void) sscanf(token, "%d", &(symbol_table[temp_index].a));
X 
X 	if (symbol_table[temp_index].a == 0)
X 		{
X 		fprintf(stderr, "read a 0 for A in DS\n");
X 		cif_output(stderr, cif);
X 		symbol_table[temp_index].a = 1;
X 		}
X 
X 	last_read = get_token(cif, last_read, token);
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "A but no B in DS\n");
X 		cif_output(stderr, cif);
X 		a_over_b = ((float) symbol_table[temp_index].a) /
X 					((float) symbol_table[temp_index].b);
X 		return;
X 		}
X 	(void) sscanf(token, "%d", &(symbol_table[temp_index].b));
X 
X 	if (symbol_table[temp_index].b == 0)
X 		{
X 		fprintf(stderr, "read a 0 for B in DS\n");
X 		cif_output(stderr, cif);
X 		symbol_table[temp_index].b = 1;
X 		}
X 	a_over_b = ((float) symbol_table[temp_index].a) /
X 					((float) symbol_table[temp_index].b);
X }	/*ds*/
X 
X 
X 	int
X get_token(cif, from, token)	/* copies token into *token */
X char	*cif;
X int	from;
X char	*token;
X {
X 	int	i;
X 
X 	/* passed end of cif statement yet? */
X 	if ((from > 0) && (cif[from - 1] == '\0'))
X 		return(-1);
X 
X 	/* skip leading white space */
X 	while (cif[from] == WHITE) from++;
X 
X 	for (i = 0; ((cif[i+from] != WHITE) && (cif[i+from] != COMMA));i++)
X 		{
X 		if (i >= MAXTOKEN-1) {
X 		  fprintf(stderr,"token overflow!\n");
X 		  cif_output(stderr,cif);
X 		  exit(1);
X 		}
X 		if (cif[i + from] == '\0')
X 			break;
X 		token[i] = cif[i + from];
X 		}
X 
X 	token[i] = '\0';
X 	if (i == 0)
X 		return(-1);
X 	else
X 		return(i + from + 1);
X }	/*get_token*/
X 
X 
X df()
X {
X 	current_symbol_index = 0;
X 	present_symbol = symbol_table[current_symbol_index].pointer;
X }	/*df*/
X 
X 
X cif_box(cif)
X char	*cif;
X {
X int	next_one, i;
X int	temp[4];
X char	token[MAXTOKEN];
X boxtype	*box, *allocbox();
X 
X 	bang_symbol();
X 	present_symbol->typer = BOXTYPE;
X 	box = allocbox();
X 	present_symbol->primitive.box = box;
X 
X 	box->layer = layer;
X 
X 	next_one = 1; /* space optional */
X 	for(i = 0; i < 4; i++) {
X 		next_one = get_token(cif, next_one, token);
X 		if (next_one == -1)
X 			{
X 			fprintf(stderr, "incomplete box\n");
X 			cif_output(stderr, cif);
X 			return;
X 			}
X 		(void) sscanf(token, "%d", &(temp[i]));
X 	}
X 
X 	/* *temp = width, height, center-x, center-y */
X 	box->llx = a_over_b * (temp[2] - temp[0]/2);
X 	box->urx = a_over_b * (temp[2] + temp[0]/2);
X 	box->lly = a_over_b * (temp[3] - temp[1]/2);
X 	box->ury = a_over_b * (temp[3] + temp[1]/2);
X }	/*cif_box*/
X 
X 
X 
X cif_change_layer(cif)
X char	*cif;
X 
X {
X 	char	token[MAXTOKEN];
X 
X 	if (-1 == get_token(cif, 1, token)) { /* space optional */
X 		fprintf(stderr, "Error in layer command\n");
X 		cif_output(stderr, cif);
X 		exit(1);
X 	}
X 	layer = layer_lookup(token);
X }	/*cif_change_layers*/
X 
X 
X 
X #define PATHMALLOC 4	/* number of points per malloc */
X cif_path(cif,ptpoints,ptarray)
X char *cif;	/* the input statement */
X int *ptpoints;	/* place to return number of points */
X int **ptarray;	/* place to return address of array */
X {
X 	static char *error = "can't read path";
X 	static char token[MAXTOKEN];
X 	static int x,y;
X 	int points=0;
X 	int column=0;	/* current column in cif line */
X 	int pointsMax = PATHMALLOC; /* initial size of array */
X 	int *pointsArray = (int *) malloc(
X 			(unsigned) (PATHMALLOC*2*sizeof(int)));
X 
X 	/* read all the points into the array */
X 	while(-1 != (column = get_token(cif, column, token))) {
X 	  if(1 != sscanf(token, "%d", &x)) {
X 	    fprintf(stderr,"%s point %d X\n", error, points);
X 	    cif_output(stderr,cif);
X 	    points=0;
X 	    break;
X 	  }
X 	  column = get_token(cif, column, token);
X 	  if((column == -1) || (1 != sscanf(token, "%d", &y))) {
X 	    fprintf(stderr,"%s point %d Y\n", error, points);
X 	    cif_output(stderr,cif);
X 	    points=0;
X 	    break;
X 	  }
X 
X 	  /* make sure there's room for the new X,Y */
X 	  if (points >= pointsMax) {
X 	    pointsMax += PATHMALLOC;
X 	    pointsArray = (int *) realloc((char *) pointsArray,
X 			(unsigned) (pointsMax * 2 * sizeof(int)));
X 	  }
X 	  if (!pointsArray) {
X 	    fprintf(stderr,"out of memory\n");
X 	    exit(1);
X 	  }
X 
X 	  /* store the X,Y pair in the array */
X 	  pointsArray[2*points] = x * a_over_b;
X 	  pointsArray[2*points+1] = y * a_over_b;
X 	  points++;
X 	} /* while (-1 != (column = get_token(...))) */
X 
X 	*ptpoints = points;
X 	*ptarray = pointsArray;
X } /* cif_path() */
X 
X 
X 
X cif_polygon(cif)
X char	*cif;
X {
X 	static char *error = "can't read polygon";
X 	ngontype *ngon;
X 	int points=0;
X 	int *pointsArray;
X 
X 	/* read in the path (list of points) */
X 	cif_path(&(cif[1]), &points, &pointsArray);
X 
X 	/* make sure polygon has enough points */
X 	if (points < 3) {
X 	  fprintf(stderr,"degenerate polygon\n");
X 	  cif_output(stderr,cif);
X 	  free((char *) pointsArray);
X 	  return;
X 	}
X 
X 	/* Finish up... */
X 	bang_symbol();
X 	present_symbol->typer = NGONTYPE;
X 	ngon = (ngontype *) malloc(sizeof(ngontype));
X 	present_symbol->primitive.ngon = ngon;
X 	ngon->layer = layer;
X 	ngon->numPoints = points;
X 	ngon->ptrPoints = pointsArray;
X } /* cif_polygon() */
X 
X 
X 
X cif_round(cif)
X char	*cif;
X {
X 	static char *error = "can't read roundflash %s\n";
X 	static char token[MAXTOKEN];
X 	static int x,y,r;
X 	int	column=1; /* space optional */
X 	roundtype *round;
X 
X 	column = get_token(cif, column, token);
X 	if((column == -1) || (1 != sscanf(token, "%d", &x))) {
X 	  fprintf(stderr,error,"X");
X 	  cif_output(stderr,cif);
X 	  return;
X 	}
X 
X 	column = get_token(cif, column, token);
X 	if((column == -1) || (1 != sscanf(token, "%d", &y))) {
X 	  fprintf(stderr,error,"Y");
X 	  cif_output(stderr,cif);
X 	  return;
X 	}
X 
X 	column = get_token(cif, column, token);
X 	if((column == -1) || (1 != sscanf(token, "%d", &r))) {
X 	  fprintf(stderr,error,"radius");
X 	  cif_output(stderr,cif);
X 	  return;
X 	}
X 
X 	/* Finish up... */
X 	bang_symbol();
X 	present_symbol->typer = ROUNDTYPE;
X 	round = (roundtype *) malloc(sizeof(roundtype));
X 	present_symbol->primitive.round = round;
X 	round->layer = layer;
X 	round->x = x * a_over_b;
X 	round->y = y * a_over_b;
X 	round->r = r * a_over_b;
X } /* cif_round() */
X 
X 
X 
X cif_wire(cif)
X char	*cif;
X {
X 	static char *error = "can't read wire";
X 	static char token[MAXTOKEN];
X 	static int width;
X 	int column=1;	/* current column in cif line */
X 	wiretype *wire;
X 	int points=0;
X 	int *pointsArray;
X 
X 	/* read the wire width */
X 	column = get_token(cif, column, token);
X 	if((column == -1) || (1 != sscanf(token, "%d", &width))) {
X 	  fprintf(stderr,error,"width");
X 	  cif_output(stderr,cif);
X 	  return;
X 	}
X 
X 	/* read in the path (list of points) */
X 	cif_path(&(cif[column]), &points, &pointsArray);
X 
X 	/* make sure wire has enough points */
X 	if (points < 2) {
X 	  fprintf(stderr,"degenerate wire\n");
X 	  cif_output(stderr,cif);
X 	  free((char *) pointsArray);
X 	  return;
X 	}
X 
X 	/* Finish up... */
X 	bang_symbol();
X 	present_symbol->typer = WIRETYPE;
X 	wire = (wiretype *) malloc(sizeof(wiretype));
X 	present_symbol->primitive.wire = wire;
X 	wire->layer = layer;
X 	wire->width = width * a_over_b;
X 	wire->numPoints = points;
X 	wire->ptrPoints = pointsArray;
X } /* cif_wire() */
X 
X 
X 
X nine(cif)
X char	*cif;
X {
X int	foobar;
X char	token[MAXTOKEN];
X 
X 	foobar = get_token(cif, 1, token); /* space optional */
X 	if (foobar == -1)
X 		{
X 		fprintf(stderr, "Error in 9 command\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 
X 	(void) sscanf(token, "%s", symbol_table[current_symbol_index].name);
X }	/*nine*/
X 
X 
X 
X bang_symbol()
X {
X 	present_symbol->next = allocsymbol();
X 	present_symbol = present_symbol->next;
X }	/*bang_symbol*/
X 
X 
X 
X ninety_four(cif)
X char	*cif;
X 
X {
X int	last_read;
X char	token[MAXTOKEN];
X ninety_fourtype	*ninety_four, *allocninety_four();
X 
X 	bang_symbol();
X 	present_symbol->typer = NINETY_FOURTYPE;
X 	ninety_four = allocninety_four();
X 	present_symbol->primitive.ninety_four = ninety_four;
X 
X 	last_read = get_token(cif, 2, token); /* space optional */
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "no text in ninety_four\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 	(void) sscanf(token, "%s", ninety_four->name);
X 
X 	last_read = get_token(cif, last_read, token);
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "no x in ninety_four\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 	(void) sscanf(token, "%d", &(ninety_four->x));
X 	ninety_four->x *= a_over_b;
X 
X 	last_read = get_token(cif, last_read, token);
X 	if (last_read == -1)
X 		{
X 		fprintf(stderr, "no y in ninety_four\n");
X 		cif_output(stderr, cif);
X 		return;
X 		}
X 	(void) sscanf(token, "%d", &(ninety_four->y));
X 	ninety_four->y *= a_over_b;
X 
X 	last_read = get_token(cif, last_read, token);
X 	if (last_read != -1)	/*don't need layer on 94*/
X 		ninety_four->layer = -1;
X }	/*ninety_four*/
X 
X 
X 
X calltype
X *alloccall()
X {
X unsigned	size = sizeof(calltype);
X calltype	*call;
X 
X 	call =(calltype *) malloc(size);
X 	call->symbol = -999;
X 	identity_matrix(call->matrix);
X 
X 	return(call);
X }	/*alloccall*/
X 
X 
X 
X 	ninety_fourtype
X *allocninety_four()
X {
X unsigned	size = sizeof(ninety_fourtype);
X ninety_fourtype	*ninety_four;
X 
X 	ninety_four =(ninety_fourtype *) malloc(size);
X 	ninety_four->layer = 0;
X 	ninety_four->x = 0;
X 	ninety_four->y = 0;
X 	ninety_four->name[0] = '\0';
X 
X 	return(ninety_four);
X }	/*allocninety_four*/
SHAR_EOF
if test 13422 -ne "`wc -c < 'cifgood.c'`"
then
	echo shar: error transmitting "'cifgood.c'" '(should have been 13422 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'cifplot.c'" '(3227 characters)'
if test -f 'cifplot.c'
then
	echo shar: will not over-write existing file "'cifplot.c'"
else
sed 's/^X //' << \SHAR_EOF > 'cifplot.c'
X /*
X  *	Output generation code.
X  *	See "cif2ps.c" for authors' names and addresses.
X  *	Please honor the authors by not removing their attributions.
X  */
X 
X #include "define.h"
X 
X plot_box(box)
X boxtype	*box;
X {
X 	pointpairtype ll, ur;
X 	int dx, dy;
X 
X 	if (box->layer != layer) return;
X 	get_pair(box->llx, box->lly, &ll);
X 	get_pair(box->urx, box->ury, &ur);
X 	dx = ur.x - ll.x;
X 	dy = ur.y - ll.y;
X 	printf("%d %d %d %d B %s\n",
X 	       dx, dy, ll.x, ll.y, cur_style);
X }	/*plot_box*/
X 
X plot_ngon(ngon)
X ngontype	*ngon;
X {
X 	pointpairtype point;
X 	int n = ngon->numPoints;
X 	int *a = ngon->ptrPoints;
X 
X 	if (ngon->layer != layer) return;
X 	get_pair(a[0], a[1], &point);
X 	printf("%d %d moveto %% P %d\n", point.x, point.y, n);
X 	n--; a += 2;
X 	do {
X 		get_pair(a[0], a[1], &point);
X 		printf("%d %d lineto\n", point.x, point.y);
X 		n--; a += 2;
X 	} while (n);
X 	printf("closepath %s\n", cur_style);
X }	/* plot_ngon */
X 
X plot_round(round)
X roundtype	*round;
X {
X 	pointpairtype center;
X 
X 	if (round->layer != layer) return;
X 	get_pair(round->x, round->y, &center);
X 	printf("newpath %d %d %d 0 360 arc closepath %s\n",
X 	       (int) center.x, (int) center.y,
X 	       (int) round->r, cur_style);
X }	/* plot_round */
X 
X plot_wire(wire)
X wiretype	*wire;
X {
X 	pointpairtype point;
X 	int n = wire->numPoints;
X 	int *a = wire->ptrPoints;
X 
X 	if (wire->layer != layer) return;
X 	printf("/WW %d 2 div def ",wire->width);
X 	get_pair(a[0], a[1], &point);
X 	printf("%d %d %% W %d\n", point.x, point.y, n);
X 	n--; a += 2;
X 	do {
X 		get_pair(a[0], a[1], &point);
X 		printf("%d %d Wto %s\n",
X 		       point.x, point.y, cur_style);
X 		n--; a += 2;
X 	} while (n);
X 	printf("pop pop\n");
X }	/* plot_wire */
X 
X plot_text(ninety_four)
X ninety_fourtype	*ninety_four;
X {
X 	pointpairtype	pair;
X 
X 	get_pair(ninety_four->x, ninety_four->y, &pair);
X 	plot_string(pair.x, pair.y, ninety_four->name);
X }	/*plot_text*/
X 
X plot_string(x, y, stringer)
X int x, y;
X char	*stringer;
X {
X 	printf("%d %d moveto (%s) show\n", x, y, stringer);
X }	/*plot_string*/
X 
X 
X void printStrings(p)
X char **p;
X {
X 	while(*p) puts(*p++);
X }
X 
X 
X putHeader()	/* goes before first page */
X {
X 	/* Uses globals: psheader */
X 
X 	puts("%!PS-Adobe-1.0");
X 	puts("%%Creator: cif2ps");
X 	puts("%%DocumentFonts: Helvetica");
X 	puts("%%Pages: (atend)");
X 	puts("%%EndComments");
X 	printStrings(psheader);
X 	puts("%%EndProlog\n");
X }
X 
X 
X putTrailer()		/* goes after last page */
X {
X 	/* Uses global: totpages */
X 
X 	puts("%%Trailer");
X 	printf("%%%%Pages: %d\n", totpages);
X }
X 
X 
X startPage()
X {
X 	printf("%%%%Page: %d:%d\n", pagex, pagey);
X 	printf("%d dup translate %% margins\n", (int) PAGEMARGIN);
X 
X 	if ( (width > 1) || (length > 1)) {
X 		/* multi-page plot: print the page number */
X 		printf("/Helvetica findfont ");
X 		printf("%d scalefont setfont\n", (int)DEFPOINTS);
X 		printf("0 %d moveto (Page %d,%d) show\n",
X 		       (int)(-DEFPOINTS), pagex, pagey);
X 	}
X 	printf("/Helvetica findfont %d ", font_points);
X 	printf("%g div scalefont setfont\n", scale);
X 	printf("%g dup scale %% points/centi-micron\n", scale);
X 	printf("%g %g translate %% cell_origin\n", trans_x, trans_y);
X 	if (pagex || pagey) {
X 		printf("%g %g translate %% page_origin\n",
X 			(float)(-pagex * PAGEWIDTH / scale),
X 			(float)(-pagey * PAGELENGTH / scale));
X 	}
X }
X 
X 
X finishPage()
X {
X 	printf("showpage\n");
X 	totpages++;
X }	/*epilog*/
SHAR_EOF
if test 3227 -ne "`wc -c < 'cifplot.c'`"
then
	echo shar: error transmitting "'cifplot.c'" '(should have been 3227 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'layers.c'" '(798 characters)'
if test -f 'layers.c'
then
	echo shar: will not over-write existing file "'layers.c'"
else
sed 's/^X //' << \SHAR_EOF > 'layers.c'
X /*
X  *	CIF Layer name storage and lookup functions.
X  *	See "cif2ps.c" for authors' names and addresses.
X  *	Please honor the authors by not removing their attributions.
X  */
X 
X #include "define.h"
X #include <string.h>
X #include <malloc.h>
X 
X 
X int
X layer_lookup(name)	/* assigns a unique number to each CIF layer */
X char *name;
X {
X 	int i;
X 	char *new;
X 
X 	for (i=0; i<numlayers; i++) {
X 		if (!strcmp(name,layers[i].name)) return(i);
X 	}
X 	/* layer was not found so define it */
X 	if (numlayers>=MAXLAYERS) {
X 		fprintf(stderr,"Too many layers\n");
X 		exit(1);
X 	}
X 	new = malloc(LNAMELEN+1);
X 	if (!new) {
X 		fprintf(stderr,"layer_lookup: Out of memory\n");
X 		exit(1);
X 	}
X 	layers[numlayers].name = strncpy(new,name,LNAMELEN);
X 	layers[numlayers].name[LNAMELEN] = '\0';
X 	layers[numlayers].style = 0;
X 	return(numlayers++);
X }
SHAR_EOF
if test 798 -ne "`wc -c < 'layers.c'`"
then
	echo shar: error transmitting "'layers.c'" '(should have been 798 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'styles.c'" '(3885 characters)'
if test -f 'styles.c'
then
	echo shar: will not over-write existing file "'styles.c'"
else
sed 's/^X //' << \SHAR_EOF > 'styles.c'
X /*
X  *	Style selection default table and related functions.
X  *	See "cif2ps.c" for authors' names and addresses.
X  *	Please honor the authors by not removing their attributions.
X  */
X 
X #include "define.h"
X #include <string.h>
X #include <ctype.h>
X 
X /*
X  *	Style table encoding:
X  *	The strings are pairs: LAYER, STYLE and
X  *	STYLE strings are merely PostScript except for the "G.n"
X  *	code which is special (and must be first in the string).
X  *	A spaces is required between components.
X  *
X  *	Drawing styles implemented:
X  *
X  *	"Gn"	fill with opaque gray stipple with level n where
X  *		n is a real number immediately after the 'G'.
X  *		The G must be the beginning of the string!
X  *
X  *	"n a L"	fill with lines spaced by n and rotated by a (degrees).
X  *
X  *	"X"	Put an X across the figure.
X  *
X  *	"stroke" Draw a box around the figure.
X  *			(this must be last if used).
X  */
X 
X char *default_styles[] = {	/* pairs of strings */
X 
X 	/* MOSIS SCMOS layers */
X 	"CPG", "G.3",
X 	"CCP", "G0",
X 	"CAA", "G.5",
X 	"CCA", "G0",
X 	"CMF", "8 45 L",
X 	"CMS", "8 135 L",
X 	"CVA", "G.2",
X 	"CSP", "16 45 L",
X 	"CSN", "16 135 L",
X 	"CWP", "32 45 L",
X 	"CWN", "32 135 L",
X 	"COG", "G.7",
X 
X 	/* Oct Symbolic layers */
X 	"POLY", "G.3",
X 	"COPO", "G.3 X stroke",		/* poly contact */
X 	"PDIF", "G.7 24 45 L",
X 	"COPD", "G.7 X stroke",		/* pdiff contact */
X 	"NDIF", "G.7 24 135 L",
X 	"COND", "G.7 X stroke",		/* ndiff contact */
X 	"MET1", "8 45 L",
X 	"COM2", "8 45 L 8 135 L stroke",
X 	"MET2", "8 135 L",
X 	"PWEL", "32 45 L",
X 	"COPS", "G.9 32 45 L X stroke",		/* psubs contact */
X 	"NWEL", "32 135 L",
X 	"CONS", "G.9 32 135 L X stroke",	/* nsubs contact */
X 	"GLAS", "G.7 X stroke",
X 
X 	/* MOSIS Bulk CMOS layers */
X 	"CP", "G.3",
X 	"CD", "G.5",
X 	"CM", "8 45 L",
X 	"CQ", "8 135 L",	/* metal 2 */
X 	"CM2","8 135 L",	/* metal 2, alternate name */
X 	"CC", "G0",
X 	"CV", "G.2 stroke",	/* via */
X 	"CC2","G.2 stroke",	/* via, alternate name */
X 	"CW", "23 45 L",
X 	"CS", "16 45 L",
X 	"CG", "G.7",
X 
X 	/* end of table marker -- MAKE SURE THIS STAYS! */
X 	0, 0
X };
X 
X 
X char *style_lookup(name)	/* returns style string for layer */
X char *name;
X {
X 	char **p;
X 
X 	for (p = default_styles; *p; p++) {
X 		if (!strcmp(*(p++),name)) return(*p);
X 	}
X 	fprintf(stderr,"%s: layer style not found (ignoring)\n", name);
X 	return("");
X }
X 
X style_sort()	/* determines drawing order for layers */
X {
X 	int i,j,tmp;
X 	float grays[MAXLAYERS];
X 
X 	/* the lighter (higher value) gray levels are drawn first,
X 	 * so sort into decreasing order.
X 	 */
X 
X 	/* Read the gray levels and initialize order[] */
X 	/* Also, make the ones starting with "G" come first */
X 	i = 0; j = numlayers;
X 	while (--j >= 0) {
X 		if (!layers[j].style)
X 			layers[j].style = style_lookup(layers[j].name);
X 		if (1 == sscanf(layers[j].style,
X 				"G%f",&(grays[j]))) {
X 			order[i++] = j;
X 		} else {
X 			order[j+i] = j;
X 		}
X 	}
X 	/* Now only the first (i) elements need sorting */
X 
X 	/* Sort the array into decreasing gray levels.
X 	 * An exchange sort is used on indexes in order[].
X 	 * (The number of elements is always small.)
X 	 */
X 	while (--i >= 0) {
X 		for (j=0; j<i; j++) {
X 			if (grays[order[j]] >= grays[order[i]])
X 				continue;
X 			/* swap (put in decreasing order) */
X 			tmp = order[i];
X 			order[i] = order[j];
X 			order[j] = tmp;
X 		}
X 	}
X }
X 
X int style_gray(s)	/* returns true if style uses gray fill */
X 	char *s;
X {
X 	if (*s != 'G') return(0);
X 	++s;
X 	while ( isdigit(*s) || (*s=='.') ) putchar(*s++);
X 	puts(" setgray");
X 	cur_style = "fill";
X 	return(1);
X }
X 
X 
X int style_rest(s)	/* the rest can be done in any order */
X 	char *s;
X {
X 	if (*s == 'G') {	/* skip a gray fill code (already done)  */
X 		++s;
X 		while ( isdigit(*s) || *s=='.' ) s++;
X 		while ( isspace(*s) ) s++;
X 	}
X 	if (*s == '\0') return(0);
X 	cur_style = s;
X 	return(1);
X }
X 
X 
X set_style(s)		/* set style, i.e. "CSP=stroke" */
X char *s;
X {
X 	int i;
X 	char *p;
X 
X 	p = s;
X 	while (isalnum(*p)) p++;	/* find non-alnum */
X 	if (*p) *(p++) = '\0';			/* zap it */
X 	i = layer_lookup(s);
X 	layers[i].style = p;
X }
SHAR_EOF
if test 3885 -ne "`wc -c < 'styles.c'`"
then
	echo shar: error transmitting "'styles.c'" '(should have been 3885 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'layerkey.csh'" '(501 characters)'
if test -f 'layerkey.csh'
then
	echo shar: will not over-write existing file "'layerkey.csh'"
else
sed 's/^X //' << \SHAR_EOF > 'layerkey.csh'
X #!/bin/csh -f
X # shell script to make a color/pattern key for cifplot.
X # Run this with an arg list of layer names to produce
X # CIF with a box showing each layer (on standard output).
X 
X if "$1" == "" then
X 	sh -c "echo $0\: expecting layer list as arguments. >&2"
X 	exit(1)
X endif
X 
X echo "( CIF layer key generated by $0 );"
X echo "DS 1 200 1;"
X # Write cell definitions, one cell for each layer
X set Y=1
X foreach L ($argv[1-])
X 	echo "L $L; B 2 2 1 $Y; 94 $L 1 $Y;"
X 	@ Y += 2
X end
X echo "DF;"
X echo "C 1;"
X echo End
SHAR_EOF
if test 501 -ne "`wc -c < 'layerkey.csh'`"
then
	echo shar: error transmitting "'layerkey.csh'" '(should have been 501 characters)'
fi
chmod +x 'layerkey.csh'
fi # end of overwriting check
echo shar: extracting "'everything.cif'" '(111 characters)'
if test -f 'everything.cif'
then
	echo shar: will not over-write existing file "'everything.cif'"
else
sed 's/^X //' << \SHAR_EOF > 'everything.cif'
X DS 1 100 1;
X L CMF;
X B 20 20 10 10;
X R 10 30 10;
X P 0 40
X  10 50
X  20 40;
X W 2
X   0 60
X  10 60
X  30 40
X  30 0;
X DF;
X C 1;
X E
SHAR_EOF
if test 111 -ne "`wc -c < 'everything.cif'`"
then
	echo shar: error transmitting "'everything.cif'" '(should have been 111 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'scmos-test.cif'" '(3074 characters)'
if test -f 'scmos-test.cif'
then
	echo shar: will not over-write existing file "'scmos-test.cif'"
else
sed 's/^X //' << \SHAR_EOF > 'scmos-test.cif'
X DS 1 25 2;
X 9 loadadd11;
X L CMF;
X     B 48 12 216 3210;
X     B 120 36 180 3186;
X     B 36 12 138 3162;
X C 2 MX R 0 -1 T 12 3348;
X C 3 R 0 -1 T 276 3996;
X C 3 R 0 -1 T 876 3996;
X C 3 R 0 -1 T 1476 3996;
X C 3 R 0 -1 T 2076 3996;
X C 3 R 0 -1 T 2676 3996;
X DF;
X DS 3 25 2;
X 9 latch_left_pair;
X L CMF;
X     B 48 48 804 540;
X     B 36 36 810 498;
X     B 48 36 816 462;
X     B 48 36 816 162;
X     B 36 84 810 102;
X     B 48 48 804 36;
X C 2 MX R 1 0 T 648 336;
X C 2 R -1 0 T 648 240;
X DF;
X DS 2 25 2;
X 9 latch;
X L CWP;
X     B 888 168 252 0;
X     B 120 24 204 -96;
X L CMS;
X     B 96 300 -228 126;
X     B 420 48 450 252;
X     B 240 48 -12 204;
X     B 48 60 84 150;
X     B 48 48 480 144;
X     B 48 36 -12 90;
X     B 36 48 474 96;
X     B 528 48 228 48;
X     B 564 48 6 -48;
X     B 96 300 612 78;
X L CMF;
X     B 108 48 234 252;
X     B 48 48 -108 204;
X     B 48 84 -12 186;
X     B 120 36 -48 126;
X     B 48 108 84 174;
X     B 60 48 198 204;
X     B 48 12 372 222;
X     B 72 36 360 198;
X     B 48 48 468 204;
X     B 48 12 576 222;
X     B 72 36 588 198;
X     B 36 84 -90 66;
X     B 48 48 -12 84;
X     B 36 96 90 72;
X     B 36 72 342 144;
X     B 36 12 474 174;
X     B 48 24 480 156;
X     B 216 36 252 90;
X     B 108 24 450 132;
X     B 96 24 444 108;
X     B 48 12 168 66;
X     B 36 24 342 60;
X     B 36 36 474 78;
X     B 60 48 -102 0;
X     B 144 36 36 6;
X     B 48 12 -12 -18;
X     B 48 12 84 -18;
X     B 48 48 204 0;
X     B 72 36 360 30;
X     B 60 36 486 42;
X     B 36 156 606 102;
X     B 48 36 372 -6;
X     B 48 48 504 0;
X     B 48 48 612 0;
X     B 108 48 234 -48;
X L CPG;
X     B 24 300 -60 102;
X     B 24 300 36 102;
X     B 24 120 132 168;
X     B 24 96 324 180;
X     B 48 12 420 138;
X     B 132 24 378 120;
X     B 24 144 528 180;
X     B 72 48 156 84;
X     B 24 84 132 18;
X     B 24 132 324 42;
X     B 48 12 420 102;
X     B 36 24 522 96;
X     B 24 24 516 72;
X     B 24 192 624 156;
X     B 84 24 486 48;
X     B 84 24 594 48;
X     B 24 84 456 -6;
X     B 24 84 564 -6;
X L CAA;
X     B 48 48 204 252;
X     B 48 24 -12 216;
X     B 48 24 84 216;
X     B 60 24 198 216;
X     B 48 24 372 216;
X     B 432 24 180 192;
X     B 48 24 468 216;
X     B 48 24 576 216;
X     B 156 24 522 192;
X     B 144 24 -60 12;
X     B 48 24 -108 -12;
X     B 48 24 -12 -12;
X     B 336 24 228 12;
X     B 48 24 84 -12;
X     B 48 72 204 -36;
X     B 48 24 372 -12;
X     B 156 24 558 12;
X     B 48 24 504 -12;
X     B 48 24 612 -12;
X L CVA;
X     B 24 24 264 252;
X     B 24 24 -108 204;
X     B 24 24 84 144;
X     B 24 24 480 144;
X     B 24 24 -12 84;
X     B 24 24 264 -48;
X L CCA;
X     B 24 24 -12 204;
X     B 24 24 84 204;
X     B 24 24 198 204;
X     B 24 24 372 204;
X     B 24 24 468 204;
X     B 24 24 576 204;
X     B 24 24 -108 0;
X     B 24 24 -12 0;
X     B 24 24 84 0;
X     B 24 24 204 0;
X     B 24 24 372 0;
X     B 24 24 504 0;
X     B 24 24 612 0;
X L CCA;
X     B 24 24 204 252;
X     B 24 24 204 -48;
X L CCP;
X     B 24 24 420 120;
X     B 24 24 168 84;
X L CSP;
X     B 240 24 60 240;
X     B 300 24 474 240;
X     B 684 72 282 192;
X     B 96 72 204 -60;
X 94 GND -120 -48 CMS;
X 94 phi1_bar 456 -48 CPG;
X 94 Vdd 468 276 CMS;
X 94 phi1 564 -48 CPG;
X 94 in 636 0;
X 94 Vdd 612 -72 CMS;
X 94 out -108 204 CMF;
X 94 i1 504 0;
X 94 i2 168 84;
X 94 phi2 -60 252 CPG;
X 94 phi2_bar 36 252 CPG;
X DF;
X C 1;
X End
SHAR_EOF
if test 3074 -ne "`wc -c < 'scmos-test.cif'`"
then
	echo shar: error transmitting "'scmos-test.cif'" '(should have been 3074 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0

Gordon W. Ross    gwr@gomez.mitre.org    (617) 271-3205 (daytime)
The MITRE Corp. (M/S E025)  Burlington Road, Bedford, MA 01730


