[comp.lsi] EDIF to CIF|PostScript|flatEDIF Sources

heeb@ethz.UUCP (Hansruedi Heeb) (05/10/88)

I received lots of requests for my EDIF to (KIC-)CIF translator.
So here it is. It's COMMON LISP (with LOOP macro).
I have no CIF to EDIF translator (I would like to...)
but I included my other EDIF stuff: EDIF to PostScript(TM) and
EDIF to flat EDIF (no instances).
Please note that these are quick hacks (less than a day each).
So don't expect too much.
I will probably not have time for new versions etc., but please
send me bug-reports/extensions anyway.

	Regards,
	Hansruedi Heeb

----------- cut here -------------
# To unbundle, sh this file
echo README 1>&2
sed 's/.//' >README <<'//GO.SYSIN DD README'
-
-Version 0
-
-All tools are for EDIF 2 0 0 (viewtype masklayout).
-The code is written in COMMON-LISP (with LOOP-macro).
-
-edifflat.l:	EDIF to flat EDIF
-ediftocif.l:	EDIF to KIC-dialect of CIF
-ediftops.l:	EDIF to PostScript
-macro.l:	needed for all other Programs
-header.ps:	Header file for PostScript output
-
-Set *path* to whatever the path of the input files is.
-CIF-files are created in the subdirectory 'cif' of *path*.
-Ediftops expects a flat EDIF-file (instances are simply ignored).
-Only paths and rectangles are recognized.
-
-Call:
-
-    (edifflat "name-of-file-without-extension")
-    (ediftocif "name-of-file-without-extension")
-    (ediftops "name-of-file-without-extension")
-
-Optional arguments:
-
-    :library 'name-of-library	(default: first library)
-    :view 'name-of-view		(default: first view)
-    :cell 'name-of-cell		(default: the whole design)
-
-Print PostScript:
-
-    cat header.ps file-name.ps | lpr -h
-
-Extensions:
-
-    .edif .fedif .ps
-
-Bugs:
-
-  - The interface section of EDIF is ignored (no labels etc.)
-  - Scale assumed to be 1/100 micron in 'ediftocif' (not checked)
-  - The scaling of the PostScript output must be done by hand
-    (last lines of 'header.ps')
-  - The code is slooow
-  - ...
-
-Disclaimer:
-   These files are all quick hacks (less than a day each).
-   Don't expect them to be bug-free!
-
-Send extensions/bug reports/flames to:  heeb@ethz (on UUCP) or
-
-	Hansruedi Heeb
-	Integrated Systems Lab
-	Swiss Federal Institute of Technology (ETH)
-	CH-8092 Zurich
-	Switzerland
//GO.SYSIN DD README
echo edifflat.l 1>&2
sed 's/.//' >edifflat.l <<'//GO.SYSIN DD edifflat.l'
-;;; -*- Syntax: Common-Lisp; Package: CL-USER; Base: 10; Mode: LISP -*-
-;;;
-;;; Edifflat (turn EDIF into a single cell flat representation)
-;;; ********
-;;; 
-;;; Version 0
-;;; 
-;;; Copyright 1988 by Hansruedi Heeb (heeb@ethz)
-;;; 
-;;; Permission to copy without fee all of this material is granted
-;;; provided that the copies are not made or distributed for direct
-;;; commercial advantage and that this copyright notice is included
-;;; in the copy.
-;;;
-(defvar *edifflat-view* nil)
-(defvar *edifflat-technology-data* nil)
-(defvar *edifflat-cell-name* nil)
-(defvar *edifflat-cells* nil)
-;;;
-;;; get-edif-time-stamp
-;;; -------------------
-;;;
-(defun get-edif-time-stamp ()
-    (cdddr (reverse (multiple-value-list (get-decoded-time))))
-)
-;;;
-;;; edif-orientation-to-matrix
-;;; --------------------------
-;;; 
-;;; Not tested in detail ...
-;;;
-(defun edif-orientation-to-matrix (or)
-    (cond
-	((eq or 'r0)
-	    '(
-		1 0
-		0 1
-	    )
-	)
-	((eq or 'r90)
-	    '(
-		0 -1
-		1 0
-	    )
-	)
-	((eq or 'r180)
-	    '(
-		-1 0
-		0 -1
-	    )
-	)
-	((eq or 'r270)
-	    '(
-		0 1
-		-1 0
-	    )
-	)
-	((eq or 'mx)
-	    '(
-		1 0
-		0 -1
-	    )
-	)
-	((eq or 'my)
-	    '(
-		-1 0
-		0 1
-	    )
-	)
-	((eq or 'mxr90)
-	    '(
-		0 1
-		1 0
-	    )
-	)
-	((eq or 'myr90)
-	    '(
-		0 -1
-		-1 0
-	    )
-	)
-	(t (error "Illegal orientation"))
-    )
-)
-;;;
-;;; edifflat-transform
-;;; ------------------
-;;;
-(defun edifflat-transform (data)
-    (loop
-	with matrix
-	with origin-pt = '(0 0)
-	with orientation = 'r0
-	for list in (cdr data)
-	for list-head = (car list)
-	when (eq list-head 'origin)
-	do
-	(setq origin-pt (cdadr list))
-	when (eq list-head 'orientation)
-	do
-	(setq orientation (cadr list))
-	when (or (eq list-head 'scalex) (eq list-head 'scaley))
-	do
-	(error "Restriction: No scaling in instanciation")
-	finally
-	(setq matrix (edif-orientation-to-matrix orientation))
-	(return (cons matrix origin-pt))
-    )
-)
-;;;
-;;; edifflat-transform-point
-;;; ------------------------
-;;;
-(defun edifflat-transform-point (point matrix vector)
-    (let (x y a00 a01 a10 a11 v0 v1)
-	(setq x (cadr point) y (caddr point))
-	(setq a00 (first matrix) a01 (second matrix))
-	(setq a10 (third matrix) a11 (fourth matrix))
-	(setq v0 (car vector) v1 (cadr vector) )
-	(list 'pt
-	    (+ (* a00 x) (* a01 y) v0)
-	    (+ (* a10 x) (* a11 y) v1)
-	)
-    )
-)
-;;;
-;;; edifflat-transform-path
-;;; -----------------------
-;;;
-(defun edifflat-transform-path (data matrix vector)
-    (cons 'path
-	(loop
-	    for point in (cdr data)
-	    collect (edifflat-transform-point point matrix vector)
-	)
-    )
-)
-;;;
-;;; edifflat-transform-rectangle
-;;; ----------------------------
-;;;
-(defun edifflat-transform-rectangle (data matrix vector)
-    (list 'rectangle
-	(edifflat-transform-point (cadr data) matrix vector)
-	(edifflat-transform-point (caddr data) matrix vector)
-    )
-)
-;;;
-;;; edifflat-transform-figures
-;;; --------------------------
-;;;
-(defun edifflat-transform-figure (figure matrix vector)
-    (cons 'figure
-	(cons (cadr figure)
-	    (loop
-		for list in (cddr figure)
-		for list-head = (car list)
-		when (eq list-head 'path)
-		collect
-		(edifflat-transform-path list matrix vector)
-		else
-		when (eq list-head 'rectangle)
-		collect
-		(edifflat-transform-rectangle list matrix vector)
-	    )
-	)
-    )
-)
-(defun edifflat-transform-figures (figures matrix vector)
-    (loop
-	for figure in figures
-	collect (edifflat-transform-figure figure matrix vector)
-    )
-)
-;;;
-;;; edifflat-instance
-;;; -----------------
-;;;
-(defun edifflat-viewref (data)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'cellref)
-	return (cadr list)
-    )
-)
-(defun edifflat-instance (data)
-    (loop
-	with cell-name
-	with transformation
-	with matrix
-	with vector
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'transform)
-	do
-	(setq transformation
-	    (edifflat-transform list)
-	)
-	(setq matrix (car transformation))
-	(setq vector (cdr transformation))
-	when (eq list-head 'viewref)
-	do
-	(setq cell-name
-	    (edifflat-viewref list)
-	)
-	finally
-	(return
-	    (loop
-		for cell-data in *edifflat-cells*
-		when (eq (car cell-data) cell-name)
-		return
-		(edifflat-transform-figures (cdr cell-data)
-		    matrix vector
-		)
-	    )
-	)
-    )
-)
-;;;
-;;; edifflat-contents
-;;; -----------------
-;;;
-(defun edifflat-contents (data)
-    (loop
-	for list in (cdr data)
-	for list-head = (car list)
-	when (eq list-head 'figure)
-	collect list
-	else
-	when (eq list-head 'instance)
-	append
-	(edifflat-instance list)
-    )
-)
-;;;
-;;; edifflat-view
-;;; -------------
-;;; 
-;;; Ignore 'interface.
-;;;
-(defun edifflat-view (data)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'contents)
-	return
-	(edifflat-contents list)
-	when (eq list-head 'viewtype)
-	do
-	(if! (not (eq (cadr list) 'masklayout)) then
-	    (error "This view is not a mask-layout view!")
-	)
-    )
-)
-;;; 
-;;; edifflat-cell
-;;; -------------
-;;;
-(defun edifflat-cell (data)
-    (loop
-	with figures
-	with cell-name = (cadr data)
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'view)
-	do
-	(if! (null *edifflat-view*) then
-	    (setq *edifflat-view* (cadr list))
-	)
-	(return
-	    (if! (eq *edifflat-view* (cadr list)) then
-		(setq figures
-		    (edifflat-view list)
-		)
-		(if! (eq *edifflat-cell-name* cell-name)
-		    then
-		    (list
-			(list 'cell cell-name
-			    (list 'celltype 'generic)
-			    (list 'view *edifflat-view*
-				(list 'viewtype 'masklayout)
-				'(interface)
-				(cons 'contents figures)
-			    )
-			)
-		    )
-		    else
-		    (push (cons cell-name figures) *edifflat-cells*)
-		    nil
-		)
-	    )
-	)
-    )
-)
-;;;
-;;; edifflat-library
-;;; ----------------
-;;;
-(defun edifflat-library (data cell)
-    (cons 'library
-	(cons (cadr data)
-	    (loop
-		for list in (cddr data)
-		for list-head = (car list)
-		when
-		(and (eq list-head 'cell)
-		    (or (null cell) (eq cell (cadr list)))
-		)
-		append (edifflat-cell list)
-		else
-		collect list
-	    )
-	)
-    )
-)
-;;; 
-;;; edifflat
-;;; --------
-;;; 
-(defun edifflat (name &key (view nil) (library nil) (cell nil))
-    (setq *edifflat-view* view)
-    (setq *edifflat-cell-name* cell)
-    (let (input-data status-data new-data)
-	(with-open-file
-	    (in-stream
-		(format nil "~A//~A.edif" *path* name)
-		:direction :input
-	    )
-	    (setq input-data (read in-stream))
-	)
-	(if! (not (eql (car input-data) 'edif)) then
-	    (error "Not an EDIF file")
-	)
-	(if! (null *edifflat-cell-name*) then
-	    (loop
-		for list in (cddr input-data)
-		for list-head = (car list)
-		when (eq list-head 'design)
-		do
-		(loop
-		    for sub-list in (cddr list)
-		    for sub-list-head = (car sub-list)
-		    when (eq sub-list-head 'cellref)
-		    do
-		    (setq *edifflat-cell-name* (cadr sub-list))
-		    (loop
-			for sub-sub-list in (cddr sub-list)
-			for sub-sub-list-head = (car sub-sub-list)
-			when (eq sub-sub-list-head 'libraryref)
-			do
-			(setq library (cadr sub-sub-list))
-		    )
-		)
-		when (eq list-head 'status)
-		do (setq status-data list)
-	    )
-	    (if! (null *edifflat-cell-name*) then
-		(error "Either specify :cell or have design in input")
-	    )
-	)
-	(if! status-data then
-	    (setq status-data
-		(append status-data
-		    (list
-			(list 'timestamp
-			    (get-edif-time-stamp) ; from edif.l
-			)
-			(list 'written
-			    (list 'program "EdifFlat")
-			)
-		    )
-		)
-	    )
-	)
-	(setq new-data
-	    (loop
-		with ok-flag = nil
-		for list in (cddr input-data)
-		for list-head = (car list)
-		when
-		(and (eq list-head 'library)
-		    (or (null library) (eq (cadr list) library))
-		)
-		do
-		(if! (null ok-flag) then
-		    (error "Must be version 2 EDIF")
-		)
-		and collect (edifflat-library list cell)
-		else
-		when (eq list-head 'status)
-		collect status-data
-		else collect list
-		when (eq list-head 'edifversion)
-		do
-		(if! (eql (cadr list) 2) then
-		    (setq ok-flag t)
-		)
-	    )
-	)
-	(setq new-data (cons 'edif (cons (cadr input-data) new-data)))
-	(with-open-file
-	    (stream
-		(format nil "~A//~A.fedif" *path* name)
-		:direction :output
-	    )
-	    (prin1 new-data stream)
-	    (terpri stream)
-	)
-    )
-)
//GO.SYSIN DD edifflat.l
echo ediftocif.l 1>&2
sed 's/.//' >ediftocif.l <<'//GO.SYSIN DD ediftocif.l'
-;;; -*- Syntax: Common-Lisp; Package: CL-USER; Base: 10; Mode: LISP -*-
-;;;
-;;; Ediftocif
-;;; *********
-;;; 
-;;; Version 0
-;;; 
-;;; Copyright 1988 by Hansruedi Heeb (heeb@ethz)
-;;; 
-;;; Permission to copy without fee all of this material is granted
-;;; provided that the copies are not made or distributed for direct
-;;; commercial advantage and that this copyright notice is included
-;;; in the copy.
-;;;
-(defvar *ediftocif-view* nil)
-(defvar *ediftocif-technology-data* nil)
-(defvar *ediftocif-current-width* nil)
-;;;
-;;; ediftocif-rectangle
-;;; -------------------
-;;; 
-;;; Not tested ...
-;;;
-(defun ediftocif-rectangle (data cif-stream)
-    (let (pt1 pt2 x1 y1 x2 y2)
-	(setq pt1 (cadr data))
-	(setq pt2 (caddr data))
-	(setq x1 (cadr pt1))
-	(setq y1 (caddr pt1))
-	(setq x2 (cadr pt2))
-	(setq y2 (caddr pt2))
-	(prls cif-stream "B "
-	    (abs (- x1 x2)) ","
-	    (abs (- y1 y2)) " "
-	    (floor (+ x1 x2) 2) "," ; must be integer ...
-	    (floor (+ y1 y2) 2) ";"
-	)
-    )
-)
-;;;
-;;; ediftocif-path
-;;; --------------
-;;;
-(defun ediftocif-path (data cif-stream)
-    (prs cif-stream "W " *ediftocif-current-width*)
-    (loop
-	for point in (cdr data)
-	do (prs cif-stream " " (cadr point) "," (caddr point))
-    )
-    (prls cif-stream ";")
-)
-;;;
-;;; edif-orientation-to-cif-orientation
-;;; -----------------------------------
-;;; 
-;;; Not tested in detail ...
-;;;
-(defun edif-orientation-to-cif-orientation (or)
-    (cond
-	((eq or 'r0) "")
-	((eq or 'r90) "R 0 1 ")
-	((eq or 'r180) "R -1 0 ")
-	((eq or 'r270) "R 0 -1 ")
-	((eq or 'mx) "MY ") ; sic !!
-	((eq or 'my) "MX ") ; sic !!
-	((eq or 'mxr90) "MY R 0 1 ")
-	((eq or 'myr90) "MX R 0 1 ")
-	(t (error "Illegal orientation"))
-    )
-)
-;;;
-;;; ediftocif-transform
-;;; -------------------
-;;;
-(defun ediftocif-transform (data)
-    (loop
-	with origin-pt = '(pt 0 0)
-	with orientation = 'r0
-	for list in (cdr data)
-	for list-head = (car list)
-	when (eq list-head 'origin)
-	do
-	(setq origin-pt (cadr list))
-	when (eq list-head 'orientation)
-	do
-	(setq orientation (cadr list))
-	when (or (eq list-head 'scalex) (eq list-head 'scaley))
-	do
-	(error "Restriction: No scaling in instanciation")
-	finally
-	(return
-	    (format nil "~AT ~D ~D"
-		(edif-orientation-to-cif-orientation orientation)
-		(cadr origin-pt) (caddr origin-pt)
-	    )
-	)
-    )
-)
-;;;
-;;; ediftocif-instance
-;;; ------------------
-;;;
-(defun ediftocif-viewref (data)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'cellref)
-	return (cadr list)
-    )
-)
-(defun ediftocif-instance (data cif-stream)
-    (loop
-	with cell-name
-	with transform-string
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'transform)
-	do
-	(setq transform-string
-	    (ediftocif-transform list)
-	)
-	when (eq list-head 'viewref)
-	do
-	(setq cell-name
-	    (ediftocif-viewref list)
-	)
-	finally
-	(prls cif-stream "9 " cell-name ";")
-	(prls cif-stream "C 0 " transform-string ";")
-    )
-)
-;;;
-;;; ediftocif-figure
-;;; ----------------
-;;;
-(defun ediftocif-figure (data cif-stream)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'path)
-	do
-	(ediftocif-path list cif-stream)
-	when (eq list-head 'rectangle)
-	do
-	(ediftocif-rectangle list cif-stream)
-    )
-)
-;;;
-;;; edif-mask-to-cif-mask
-;;; ---------------------
-;;;
-(defun edif-mask-to-cif-mask (edif-mask)
-    (cond
-	((eq edif-mask 'metal) 'CM)
-	((eq edif-mask 'metal1) 'CM)
-	((eq edif-mask 'metal2) 'CM2)
-	((eq edif-mask 'poly) 'CP)
-	((eq edif-mask 'ndiffusion) 'CD)
-	((eq edif-mask 'pdiffusion) 'CD)
-	((eq edif-mask 'mpcontact) 'CC)
-	((eq edif-mask 'mdcontact) 'CC)
-	((eq edif-mask 'mmcontact) 'CC)
-	(t (error (format nil "Unknown mask ~A" edif-mask)))
-    )
-)
-;;;
-;;; ediftocif-contents
-;;; ------------------
-;;;
-(defun ediftocif-contents (data cif-stream)
-    (loop
-	for list in (cdr data)
-	for list-head = (car list)
-	when (eq list-head 'figure)
-	do
-	(prls cif-stream "L " (edif-mask-to-cif-mask (cadr list)) ";")
-	(setq *ediftocif-current-width*
-	    (loop
-		with edif-mask = (cadr list)
-		for p-list in *ediftocif-technology-data*
-		when (eq (car p-list) edif-mask)
-		return (cdr p-list)
-	    )
-	)
-	(ediftocif-figure list cif-stream)
-	when (eq list-head 'instance)
-	do
-	(ediftocif-instance list cif-stream)
-    )
-)
-;;;
-;;; ediftocif-view
-;;; --------------
-;;; 
-;;; Ignore 'interface.
-;;;
-(defun ediftocif-view (data cif-stream)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'contents)
-	do
-	(ediftocif-contents list cif-stream)
-	when (eq list-head 'viewtype)
-	do
-	(if! (not (eq (cadr list) 'masklayout)) then
-	    (error "This view is not a mask-layout view!")
-	)
-    )
-)
-;;; 
-;;; ediftocif-cell
-;;; --------------
-;;;
-(defun ediftocif-cell (data)
-    (loop
-	with cell-name = (cadr data)
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'view)
-	do
-	(if! (null *ediftocif-view*) then
-	    (setq *ediftocif-view* (cadr list))
-	)
-	(if! (eq *ediftocif-view* (cadr list)) then
-	    (with-open-file
-		(cif-stream
-		    (format nil "~A//cif//~A" *path* cell-name)
-		    :direction :output
-		)
-		(prls cif-stream "9 " cell-name ";")
-		(prls cif-stream "DS 0 1,1;")
-		(ediftocif-view list cif-stream)
-		(prls cif-stream "DF;")
-		(prls cif-stream "E")
-	    )
-	)
-    )
-)
-;;;
-;;; ediftocif-technology
-;;; --------------------
-;;;
-(defun ediftocif-technology (data)
-    (setq *ediftocif-technology-data*
-	(loop
-	    for list in (cddr data)
-	    for list-head = (car list)
-	    when (eq list-head 'figuregroup)
-	    collect
-	    (loop
-		for sub-list in (cddr list)
-		for sub-list-head = (car sub-list)
-		when (eq sub-list-head 'pathwidth)
-		return (cons (cadr list) (cadr sub-list))
-	    )
-	)
-    )
-)
-;;;
-;;; ediftocif-library
-;;; -----------------
-;;;
-(defun ediftocif-library (data cell)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'technology)
-	do
-	(ediftocif-technology list)
-	when (eq list-head 'cell)
-	do
-	(if! (or (null cell) (eq cell (cadr list))) then
-	    (ediftocif-cell list)
-	)
-    )
-)
-;;; 
-;;; ediftocif
-;;; ---------
-;;; 
-(defun ediftocif (name &key (view nil) (library nil) (cell nil))
-    (setq *ediftocif-view* view)
-    (let (input-data)
-	(with-open-file
-	    (in-stream
-		(format nil "~A//~A.edif" *path* name)
-		:direction :input
-	    )
-	    (setq input-data (read in-stream))
-	)
-	(if! (not (eql (car input-data) 'edif)) then
-	    (error "Not an EDIF file")
-	)
-	(loop
-	    with ok-flag = nil
-	    for list in (cddr input-data)
-	    for list-head = (car list)
-	    when (eq list-head 'edifversion)
-	    do
-	    (if! (eql (cadr list) 2) then
-		(setq ok-flag t)
-	    )
-	    when (eq list-head 'library)
-	    do
-	    (if! (or (null library) (eq (cadr list) library)) then
-		(if! (null ok-flag) then
-		    (error "Must be version 2 EDIF")
-		)
-		(ediftocif-library list cell)
-		(return nil)
-	    )
-	)
-    )
-)
//GO.SYSIN DD ediftocif.l
echo ediftops.l 1>&2
sed 's/.//' >ediftops.l <<'//GO.SYSIN DD ediftops.l'
-;;; -*- Syntax: Common-Lisp; Package: CL-USER; Base: 10; Mode: LISP -*-
-;;;
-;;; Ediftops (EDIF to PostScript)
-;;; ********
-;;; 
-;;; Version 0
-;;; 
-;;; Copyright 1988 by Hansruedi Heeb (heeb@ethz)
-;;; 
-;;; Permission to copy without fee all of this material is granted
-;;; provided that the copies are not made or distributed for direct
-;;; commercial advantage and that this copyright notice is included
-;;; in the copy.
-;;;
-(defvar *ediftops-view* nil)
-(defvar *ediftops-technology-data* nil)
-(defvar *ediftops-current-width* nil)
-(defvar *ediftops-current-mask* nil)
-(defvar *ediftops-name* nil)
-;;;
-;;; ediftops-plot-rectangle
-;;; -----------------------
-;;;
-(defun ediftops-plot-rectangle (x1 y1 x2 y2 ps-stream)
-    (prls ps-stream
-	x1 " " y1 " " x1 " " y2 " " x2 " " y2 " " x2 " " y1 " "
-	*ediftops-current-mask* "R"
-    )
-)
-;;;
-;;; ediftops-rectangle
-;;; ------------------
-;;;
-(defun ediftops-rectangle (data ps-stream)
-    (let (pt1 pt2 x1 y1 x2 y2)
-	(setq pt1 (cadr data))
-	(setq pt2 (caddr data))
-	(setq x1 (floor (cadr pt1) 10) y1 (floor (caddr pt1) 10))
-	(setq x2 (floor (cadr pt2) 10) y2 (floor (caddr pt2) 10))
-	(ediftops-plot-rectangle x1 y1 x2 y2 ps-stream)
-    )
-)
-;;;
-;;; ediftops-path-segment
-;;; ---------------------
-;;;
-(defun ediftops-path-segment (pt1 pt2 ps-stream)
-    (let (x1 x2 y1 y2)
-	(setq x1 (floor (cadr pt1) 10) y1 (floor (caddr pt1) 10))
-	(setq x2 (floor (cadr pt2) 10) y2 (floor (caddr pt2) 10))
-	(prls ps-stream
-	    *ediftops-current-width* " " x1 " " y1 " " x2 " " y2
-	    " " *ediftops-current-mask*
-	)
-    )
-)
-;;;
-;;; ediftops-path
-;;; -------------
-;;;
-(defun ediftops-path (data ps-stream)
-    (if! (= (length data) 2) then
-	(ediftops-path-segment (cadr data) (cadr data) ps-stream)
-	else
-	(loop
-	    with prev-point = (cadr data)
-	    for point in (cddr data)
-	    do
-	    (ediftops-path-segment prev-point point ps-stream)
-	    (setq prev-point point)
-	)
-    )
-)
-;;;
-;;; ediftops-figure
-;;; ---------------
-;;;
-(defun ediftops-figure (data ps-stream)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'path)
-	do
-	(ediftops-path list ps-stream)
-	when (eq list-head 'rectangle)
-	do
-	(ediftops-rectangle list ps-stream)
-    )
-)
-;;;
-;;; edif-mask-to-ps-macro
-;;; ---------------------
-;;;
-(defun edif-mask-to-ps-macro (edif-mask)
-    (cond
-	((eq edif-mask 'metal) 'CM)
-	((eq edif-mask 'metal1) 'CM)
-	((eq edif-mask 'metal2) 'CM2)
-	((eq edif-mask 'poly) 'CP)
-	((eq edif-mask 'ndiffusion) 'CD)
-	((eq edif-mask 'pdiffusion) 'CD)
-	((eq edif-mask 'mpcontact) 'CC)
-	((eq edif-mask 'mdcontact) 'CC)
-	((eq edif-mask 'mmcontact) 'CC2)
-	(t (error (format nil "Unknown mask ~A" edif-mask)))
-    )
-)
-;;;
-;;; ediftops-figure-less
-;;; --------------------
-;;;
-(defun ediftops-mask-rating (edif-mask)
-    (cond
-	((eq edif-mask 'ndiffusion) 1)
-	((eq edif-mask 'pdiffusion) 1)
-	((eq edif-mask 'poly) 5)
-	((eq edif-mask 'metal2) 8)
-	((eq edif-mask 'metal) 12)
-	((eq edif-mask 'metal1) 12)
-	((eq edif-mask 'mpcontact) 20)
-	((eq edif-mask 'mdcontact) 20)
-	((eq edif-mask 'mmcontact) 20)
-	(t 999)
-    )
-)
-(defun ediftops-figure-less (figure1 figure2)
-    (<
-	(ediftops-mask-rating (cadr figure1))
-	(ediftops-mask-rating (cadr figure2))
-    )
-)
-;;;
-;;; ediftops-contents
-;;; -----------------
-;;;
-(defun ediftops-contents (data ps-stream)
-    (loop
-	with lists = (sort (copy-list (cdr data)) 'ediftops-figure-less)
-	for list in lists
-	for list-head = (car list)
-	when (eq list-head 'figure)
-	do
-	(setq *ediftops-current-mask* (edif-mask-to-ps-macro (cadr list)))
-	(setq *ediftops-current-width*
-	    (floor
-		(loop
-		    with edif-mask = (cadr list)
-		    for p-list in *ediftops-technology-data*
-		    when (eq (car p-list) edif-mask)
-		    return (cdr p-list)
-		)
-		10
-	    )
-	)
-	(ediftops-figure list ps-stream)
-	;when (eq list-head 'instance) ; completely ignore instances
-	;do
-	;(ediftops-instance list ps-stream)
-    )
-)
-;;;
-;;; ediftops-view
-;;; -------------
-;;; 
-;;; Ignore 'interface.
-;;;
-(defun ediftops-view (data ps-stream)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'contents)
-	do
-	(ediftops-contents list ps-stream)
-	when (eq list-head 'viewtype)
-	do
-	(if! (not (eq (cadr list) 'masklayout)) then
-	    (error "This view is not a mask-layout view!")
-	)
-    )
-)
-;;; 
-;;; ediftops-cell
-;;; -------------
-;;;
-(defun ediftops-cell (data)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'view)
-	do
-	(if! (null *ediftops-view*) then
-	    (setq *ediftops-view* (cadr list))
-	)
-	(if! (eq *ediftops-view* (cadr list)) then
-	    (with-open-file
-		(ps-stream
-		    (format nil "~A//~A.ps" *path* *ediftops-name*)
-		    :direction :output
-		)
-		(prls ps-stream "% Created by 'ediftops'")
-		(ediftops-view list ps-stream)
-		(prls ps-stream "showpage")
-	    )
-	)
-    )
-)
-;;;
-;;; ediftops-technology
-;;; -------------------
-;;;
-(defun ediftops-technology (data)
-    (setq *ediftops-technology-data*
-	(loop
-	    for list in (cddr data)
-	    for list-head = (car list)
-	    when (eq list-head 'figuregroup)
-	    collect
-	    (loop
-		for sub-list in (cddr list)
-		for sub-list-head = (car sub-list)
-		when (eq sub-list-head 'pathwidth)
-		return (cons (cadr list) (cadr sub-list))
-	    )
-	)
-    )
-)
-;;;
-;;; ediftops-library
-;;; ----------------
-;;;
-(defun ediftops-library (data cell)
-    (loop
-	for list in (cddr data)
-	for list-head = (car list)
-	when (eq list-head 'cell) do
-	(if! (or (null cell) (eq cell (cadr list))) then
-	    (ediftops-cell list)
-	    (return nil) ; do only a single cell
-	)
-	when (eq list-head 'technology) do
-	(ediftops-technology list)
-    )
-)
-;;; 
-;;; ediftops
-;;; --------
-;;; 
-(defun ediftops (name &key (view nil) (library nil) (cell nil))
-    (setq *ediftops-view* view)
-    (setq *ediftops-name* name)
-    (let (input-data)
-	(with-open-file
-	    (in-stream
-		(format nil "~A//~A.fedif" *path* name)
-		:direction :input
-	    )
-	    (setq input-data (read in-stream))
-	)
-	(if! (not (eql (car input-data) 'edif)) then
-	    (error "Not an EDIF file")
-	)
-	(loop
-	    with ok-flag = nil
-	    for list in (cddr input-data)
-	    for list-head = (car list)
-	    when (eq list-head 'edifversion)
-	    do
-	    (if! (eql (cadr list) 2) then
-		(setq ok-flag t)
-	    )
-	    when (eq list-head 'library)
-	    do
-	    (if! (or (null library) (eq (cadr list) library)) then
-		(if! (null ok-flag) then
-		    (error "Must be version 2 EDIF")
-		)
-		(ediftops-library list cell)
-		(return nil)
-	    )
-	)
-    )
-)
//GO.SYSIN DD ediftops.l
echo header.ps 1>&2
sed 's/.//' >header.ps <<'//GO.SYSIN DD header.ps'
-%!PS
-% Header file for CIF to PostScript output.
-%
-
-/cm {28.346 mul} def
-/cw {50} def % contact width
-/ch {25} def % contact half width
-/cc {25} def % contact circle radius
-
-/r
-{newpath
-  moveto
-  lineto
-  lineto
-  lineto
-  closepath
-} def
-
-/l
-{newpath
-  moveto
-  lineto
-  setlinewidth
-  2 setlinecap
-} def
-
-/c
-{newpath
-  8 setlinewidth
-  moveto
-  ch ch rmoveto
-  cw neg cw neg rlineto
-  cw 0 rmoveto
-  cw neg cw rlineto
-  pop
-  pop
-  pop
-} def
-
-/ci
-{newpath
-  ch 0 360 arc
-  pop
-  pop
-  pop
-} def
-
-/CCR
-{ r 0 setgray 10 setlinewidth stroke
-} def
-
-/CC2R
-{ r 0 setgray 10 setlinewidth stroke
-} def
-
-/CMR
-{ r 0 setgray fill
-} def
-
-/CM2R
-{ r 0.5 setgray fill
-} def
-
-/CPR
-{ r 0.8 setgray fill
-} def
-
-/CDR
-{ r 0.99 setgray fill
-} def
-
-/CC
-{ ci 0 setgray fill
-} def
-
-/CC2
-{ c 0 setgray stroke
-} def
-
-/CM
-{ l 0 setgray 20 setlinewidth stroke % ignore original width
-} def
-
-/CM2
-{ l 0.5 setgray stroke
-} def
-
-/CP
-{ l 0.8 setgray stroke
-} def
-
-/CD
-{ l 0.99 setgray stroke
-} def
-
-%
-% Change these numbers to get the right size:
-%
-2.5 cm 1.5 cm translate
-0.055 0.055 scale % points (= 1/72 inch) per 1/100 micron
-%
//GO.SYSIN DD header.ps
echo macro.l 1>&2
sed 's/.//' >macro.l <<'//GO.SYSIN DD macro.l'
-;;; -*- Syntax: Common-Lisp; Package: CL-USER; Base: 10; Mode: LISP -*-
-;;;
-;;; Macro
-;;; *****
-;;; 
-;;; Copyright 1988 by Hansruedi Heeb (heeb@ethz)
-;;; 
-;;; Permission to copy without fee all of this material is granted
-;;; provided that the copies are not made or distributed for direct
-;;; commercial advantage and that this copyright notice is included
-;;; in the copy.
-;;; 
-(defvar *path* "PIL://usr//pilatus//iis//heeb//edif//")
-;;;
-;;; if!
-;;; ---
-;;; 
-(defmacro if! (&body body)
-    (let (test then else)
-	(setq test (car body))
-	(setq body (cdr body))
-	(unless (eql (car body) 'then)
-	    (terpri *error-output*)
-	    (if (member 'then body)
-		(error "if!: misplaced then")
-		(error "if!: missing then")
-	    )
-	)
-	(setq body (cdr body))
-	(setq else (cdr (member 'else body)))
-	(if else
-	    (setq then ; a hack ...
-		(reverse (cdr (member 'else (reverse body))))
-	    )
-	    (setq then body)
-	)
-	(if else
-	    `(cond
-		(,test ,@then)
-		(t ,@else)
-	    )
-	    `(cond
-		(,test ,@then)
-	    )
-	)
-    )
-)
-;;; 
-(defun prs (stream &rest arg)
-    (loop
-	for elt in arg do (princ elt stream)
-    )
-)
-(defun prls (stream &rest arg)
-    (loop
-	for elt in arg do (princ elt stream)
-    )
-    (terpri stream)
-)
//GO.SYSIN DD macro.l