1 /* CIFtech.c -
2  *
3  *	This module processes the portions of technology
4  *	files pertaining to CIF, and builds the tables
5  *	used by the CIF generator.
6  *
7  *     *********************************************************************
8  *     * Copyright (C) 1985, 1990 Regents of the University of California. *
9  *     * Permission to use, copy, modify, and distribute this              *
10  *     * software and its documentation for any purpose and without        *
11  *     * fee is hereby granted, provided that the above copyright          *
12  *     * notice appear in all copies.  The University of California        *
13  *     * makes no representations about the suitability of this            *
14  *     * software for any purpose.  It is provided "as is" without         *
15  *     * express or implied warranty.  Export of this software outside     *
16  *     * of the United States of America may require an export license.    *
17  *     *********************************************************************
18  */
19 
20 #ifndef lint
21 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFtech.c,v 1.7 2010/10/20 20:34:19 tim Exp $";
22 #endif  /* not lint */
23 
24 #include <stdio.h>
25 #include <stdlib.h>	/* for atof()	*/
26 #include <string.h>
27 #include <ctype.h>
28 #include <math.h>	/* for pow()	*/
29 
30 #include "utils/magic.h"
31 #include "utils/geometry.h"
32 #include "tiles/tile.h"
33 #include "utils/hash.h"
34 #include "database/database.h"
35 #include "utils/tech.h"
36 #include "utils/utils.h"
37 #include "utils/styles.h"
38 #include "cif/CIFint.h"
39 #include "calma/calmaInt.h"
40 #include "textio/textio.h"
41 #include "utils/malloc.h"
42 #include "cif/cif.h"
43 #include "drc/drc.h"	/* For WRL's DRC-CIF extensions */
44 
45 /* The following statics are used to keep track of things between
46  * calls to CIFTechLine.
47  */
48 
49 static CIFLayer *cifCurLayer;	/* Current layer whose spec. is being read. */
50 static CIFOp *cifCurOp;		/* Last geometric operation read in. */
51 static bool cifGotLabels;	/* TRUE means some labels have been assigned
52 				 * to the current layer.
53 				 */
54 
55 /* The following is a TileTypeBitMask array with only the CIF_SOLIDTYPE
56  * bit set in it.
57  */
58 TileTypeBitMask CIFSolidBits;
59 
60 /* Forward Declarations */
61 
62 void cifTechStyleInit();
63 bool cifCheckCalmaNum();
64 
65 /*
66  * ----------------------------------------------------------------------------
67  *
68  * cifTechFreeStyle --
69  *
70  * 	This procedure frees memory for the current CIF style, and
71  *	sets the current style to NULL.
72  *
73  * Results:
74  *	None.
75  *
76  * Side effects:
77  *	Memory is free'd.
78  *
79  * ----------------------------------------------------------------------------
80  */
81 
82 void
cifTechFreeStyle()83 cifTechFreeStyle()
84 {
85     int i;
86     CIFOp	*op;
87     CIFLayer	*layer;
88 
89     if (CIFCurStyle != NULL)
90     {
91 	/* Destroy old style structure and free memory allocated to it */
92 
93 	for (i = 0; i < MAXCIFLAYERS; i++)
94 	{
95 	    layer = CIFCurStyle->cs_layers[i];
96 	    if (layer != NULL)
97 	    {
98 		for (op = layer->cl_ops; op != NULL; op = op->co_next)
99 		{
100 		    if (op->co_client != (ClientData)NULL)
101 		    {
102 			switch (op->co_opcode)
103 			{
104 			    case CIFOP_OR:
105 			    case CIFOP_BBOX:
106 			    case CIFOP_MAXRECT:
107 			    case CIFOP_BOUNDARY:
108 				/* These options use co_client to hold a single	*/
109 				/* integer value, so it is not allocated.	*/
110 				break;
111 			    default:
112 				freeMagic((char *)op->co_client);
113 				break;
114 			}
115 		    }
116 		    freeMagic((char *)op);
117 		}
118 		freeMagic((char *)layer);
119 	    }
120 	}
121 	freeMagic(CIFCurStyle);
122 	CIFCurStyle = NULL;
123     }
124 }
125 
126 /*
127  * ----------------------------------------------------------------------------
128  *
129  * cifTechNewStyle --
130  *
131  * 	This procedure creates a new CIF style at the end of
132  *	the list of style and initializes it to completely
133  *	null.
134  *
135  * Results:
136  *	None.
137  *
138  * Side effects:
139  *	A new element is added to the end of CIFStyleList, and CIFCurStyle
140  *	is set to point to it.
141  *
142  * ----------------------------------------------------------------------------
143  */
144 
145 void
cifTechNewStyle()146 cifTechNewStyle()
147 {
148     cifTechFreeStyle();
149     cifTechStyleInit();
150 }
151 
152 /*
153  * ----------------------------------------------------------------------------
154  *
155  * cifTechStyleInit --
156  *
157  * Fill in the current cif input style structure with initial values
158  *
159  * ----------------------------------------------------------------------------
160  */
161 
162 void
cifTechStyleInit()163 cifTechStyleInit()
164 {
165     int i;
166 
167     if (CIFCurStyle == NULL)
168 	CIFCurStyle = (CIFStyle *) mallocMagic(sizeof(CIFStyle));
169 
170     CIFCurStyle->cs_name = NULL;
171     CIFCurStyle->cs_status = TECH_NOT_LOADED;
172 
173     CIFCurStyle->cs_nLayers = 0;
174     CIFCurStyle->cs_scaleFactor = 0;
175     CIFCurStyle->cs_stepSize = 0;
176     CIFCurStyle->cs_gridLimit = 0;
177     CIFCurStyle->cs_reducer = 0;
178     CIFCurStyle->cs_expander = 1;
179     CIFCurStyle->cs_yankLayers = DBZeroTypeBits;
180     CIFCurStyle->cs_hierLayers = DBZeroTypeBits;
181     CIFCurStyle->cs_flags = 0;
182     for (i=0;  i<TT_MAXTYPES;  i+=1)
183     {
184 	CIFCurStyle->cs_labelLayer[i] = -1;
185 	CIFCurStyle->cs_portLayer[i] = -1;
186     }
187     for (i = 0; i < MAXCIFLAYERS; i++)
188 	CIFCurStyle->cs_layers[i] = NULL;
189 }
190 
191 
192 /*
193  * ----------------------------------------------------------------------------
194  *
195  * cifParseLayers --
196  *
197  * 	Takes a comma-separated list of layers and turns it into two
198  *	masks, one of paint layers and one of previously-defined CIF
199  *	layers.
200  *
201  * Results:
202  *	None.
203  *
204  * Side effects:
205  *	The masks pointed to by the paintMask and cifMask parameters
206  *	are modified.  If some of the layers are unknown, then an error
207  *	message is printed.
208  *
209  * ----------------------------------------------------------------------------
210  */
211 
212 void
cifParseLayers(string,style,paintMask,cifMask,spaceOK)213 cifParseLayers(string, style, paintMask, cifMask, spaceOK)
214     char *string;		/* List of layers. */
215     CIFStyle *style;		/* Gives CIF style for parsing string.*/
216     TileTypeBitMask *paintMask;	/* Place to store mask of paint layers.  If
217 				 * NULL, then only CIF layer names are
218 				 * considered.
219 				 */
220     TileTypeBitMask *cifMask;	/* Place to store mask of CIF layers.  If
221 				 * NULL, then only paint layer names are
222 				 * considered.
223 				 */
224     int	spaceOK;		/* are space layers permissible in this cif
225     				   layer?
226 				*/
227 {
228     TileTypeBitMask curCifMask, curPaintMask;
229     char curLayer[40], *p, *cp;
230     TileType paintType;
231     int i;
232     bool allResidues;
233 
234     if (paintMask != NULL) TTMaskZero(paintMask);
235     if (cifMask != NULL) TTMaskZero(cifMask);
236 
237     while (*string != 0)
238     {
239 	p = curLayer;
240 
241 	if (*string == '*')
242 	{
243 	    allResidues = TRUE;
244 	    string++;
245 	}
246 	else
247 	    allResidues = FALSE;
248 
249 	while ((*string != ',') && (*string != 0))
250 	    *p++ = *string++;
251 	*p = 0;
252 	while (*string == ',') string += 1;
253 
254 	/* See if this is a paint type. */
255 
256 	if (paintMask != NULL)
257 	{
258 	    paintType = DBTechNameTypes(curLayer, &curPaintMask);
259 	    if (paintType >= 0) goto okpaint;
260 	}
261 	else paintType = -2;
262 
263 okpaint:
264 	/* See if this is the name of another CIF layer.  Be
265 	 * careful not to let the current layer be used in
266 	 * generating itself.  Exact match is requred on CIF
267 	 * layer names, but the same name can appear multiple
268 	 * times in different styles.
269 	 */
270 
271 	TTMaskZero(&curCifMask);
272 	if (cifMask != NULL)
273 	{
274 	    for (i = 0;  i < style->cs_nLayers; i++)
275 	    {
276 		if (style->cs_layers[i] == cifCurLayer) continue;
277 		if (strcmp(curLayer, style->cs_layers[i]->cl_name) == 0)
278 		{
279 		    TTMaskSetType(&curCifMask, i);
280 		}
281 	    }
282 	}
283 
284 	/* Make sure that there's exactly one match among cif and
285 	 * paint layers together.
286 	 */
287 
288 	if ((paintType == -1)
289 	    || ((paintType >= 0) && !TTMaskEqual(&curCifMask, &DBZeroTypeBits)))
290 	{
291 	    TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
292 	    continue;
293 	}
294 	if (paintType >= 0)
295 	{
296 	    if (paintType == TT_SPACE && spaceOK ==0)
297 		TechError("\"Space\" layer not permitted in CIF rules.\n");
298 	    else
299 	    {
300 		TileType rtype;
301 		TileTypeBitMask *rMask;
302 
303 		TTMaskSetMask(paintMask, &curPaintMask);
304 
305 		/* Add residues from '*' notation */
306 		if (allResidues)
307 		    for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++)
308 		    {
309 			rMask = DBResidueMask(rtype);
310 			if (TTMaskHasType(rMask, paintType))
311 			    TTMaskSetType(paintMask, rtype);
312 		    }
313 	    }
314 	}
315 	else if (!TTMaskEqual(&curCifMask, &DBZeroTypeBits))
316 	{
317 	    TTMaskSetMask(cifMask, &curCifMask);
318 	}
319 	else
320 	{
321 	    HashEntry *he;
322 	    TileTypeBitMask *amask;
323 
324 	    he = HashLookOnly(&DBTypeAliasTable, curLayer);
325 	    if (he != NULL)
326 	    {
327 		amask = (TileTypeBitMask *)HashGetValue(he);
328 		TTMaskSetMask(paintMask, amask);
329 	    }
330 	    else
331 		TechError("Unrecognized layer (type) \"%s\".\n", curLayer);
332 	}
333     }
334 }
335 
336 
337 /*
338  * ----------------------------------------------------------------------------
339  *
340  * CIFTechInit --
341  *
342  * 	Called before loading a new technology.
343  *
344  * Results:
345  *	None.
346  *
347  * Side effects:
348  *	Clears out list of styles and resets the current style.
349  *
350  * ----------------------------------------------------------------------------
351  */
352 
353 void
CIFTechInit()354 CIFTechInit()
355 {
356     CIFKeep *style;
357 
358     /* Cleanup any old info. */
359 
360     cifTechFreeStyle();
361 
362     /* forget the list of styles */
363 
364     for (style = CIFStyleList; style != NULL; style = style->cs_next)
365     {
366 	freeMagic(style->cs_name);
367 	freeMagic(style);
368     }
369     CIFStyleList = NULL;
370 }
371 
372 /*
373  * ----------------------------------------------------------------------------
374  *
375  * CIFTechStyleInit --
376  *
377  * 	Called once at beginning of technology file read-in to
378  *	initialize data structures.
379  *
380  * Results:
381  *	None.
382  *
383  * Side effects:
384  *	Just clears out the layer data structures.
385  *
386  * ----------------------------------------------------------------------------
387  */
388 
389 void
CIFTechStyleInit()390 CIFTechStyleInit()
391 {
392     CalmaTechInit();
393 
394     /* Create the TileTypeBitMask array with only the CIF_SOLIDTYPE bit set */
395     TTMaskZero(&CIFSolidBits);
396     TTMaskSetType(&CIFSolidBits, CIF_SOLIDTYPE);
397 
398     cifCurOp = NULL;
399     cifCurLayer = NULL;
400     cifGotLabels = FALSE;
401 }
402 
403 /*
404  * ----------------------------------------------------------------------------
405  *
406  * CIFTechLimitScale --
407  *
408  *	Determine if the scalefactor (ns / ds), applied to the current
409  *	grid scaling, would result in a grid finer than the minimum
410  *	resolution allowed by the process, as set by the "gridlimit"
411  *	statement in the "cifoutput" section (note that the scaling
412  *	depends on the output style chosen, and can be subverted by
413  *	scaling while a fine-grid output style is active, then switching
414  *	to a coarse-grid output style).
415  *
416  *	Note that even if the scalefactor is larger than the minimum
417  *	grid, it must be a MULTIPLE of the minimum grid, or else geometry
418  *	can be generated off-grid.
419  *
420  * Results:
421  *	TRUE if scaling by (ns / ds) would violate minimum grid resolution,
422  *	FALSE if not.
423  *
424  * Side effects:
425  *	None.
426  *
427  * ----------------------------------------------------------------------------
428  */
429 
430 bool
CIFTechLimitScale(ns,ds)431 CIFTechLimitScale(ns, ds)
432     int ns, ds;
433 {
434     int gridup, scaledown;
435     int scale, limit, expand;
436 
437     if (CIFCurStyle == NULL) return FALSE;
438 
439     scale = CIFCurStyle->cs_scaleFactor;
440     limit = CIFCurStyle->cs_gridLimit;
441     expand = CIFCurStyle->cs_expander;
442 
443     if (limit == 0) limit = 1;
444 
445     gridup = limit * expand * ds;
446     scaledown = scale * ns * 10;
447 
448     if ((scaledown / gridup) == 0) return TRUE;
449     if ((scaledown % gridup) != 0) return TRUE;
450 
451     return FALSE;
452 }
453 
454 /*
455  * ----------------------------------------------------------------------------
456  *
457  * CIFParseScale --
458  *
459  *	Read a scale value and determine scaleFactor and expander values
460  *
461  * Results:
462  *	Returns the value for cs_scaleFactor
463  *
464  * Side effects:
465  *	Alters the value of expander (pointer to cs_expander)
466  *
467  * ----------------------------------------------------------------------------
468  */
469 
470 int
CIFParseScale(true_scale,expander)471 CIFParseScale(true_scale, expander)
472     char *true_scale;
473     int  *expander;
474 {
475     char *decimal;
476     short places;
477     int n, d;
478 
479     decimal = strchr(true_scale, '.');
480 
481     if (decimal == NULL)	/* true_scale is integer */
482     {
483 	*expander = 1;
484 	return atoi(true_scale);
485     }
486     else
487     {
488 	*decimal = '\0';
489 	places = strlen(decimal + 1);
490 	d = pow(10,places);
491 	n = atoi(true_scale);
492 	*decimal = '.';
493 	n *= d;
494 	n += atoi(decimal + 1);
495 	ReduceFraction(&n, &d);
496 	*expander = d;
497 	return n;
498     }
499 }
500 
501 
502 /*
503  * ----------------------------------------------------------------------------
504  *
505  * CIFTechLine --
506  *
507  * 	This procedure is called once for each line in the "cif"
508  *	section of the technology file.
509  *
510  * Results:
511  *	TRUE if line parsed correctly; FALSE if fatal error condition
512  *	encountered.
513  *
514  * Side effects:
515  *	Sets up information in the tables of CIF layers, and
516  *	prints error messages where there are problems.
517  *
518  * ----------------------------------------------------------------------------
519  */
520 
521 bool
CIFTechLine(sectionName,argc,argv)522 CIFTechLine(sectionName, argc, argv)
523     char *sectionName;		/* The name of this section. */
524     int argc;			/* Number of fields on line. */
525     char *argv[];		/* Values of fields. */
526 {
527     TileTypeBitMask mask, tempMask, cifMask, bloatLayers;
528     int i, j, l, distance;
529     CIFLayer *newLayer;
530     CIFOp *newOp = NULL;
531     CIFKeep *newStyle, *p;
532     char **bloatArg;
533     BloatData *bloats;
534     BridgeData *bridge;
535     SquaresData *squares;
536     SlotsData *slots;
537 
538     if (argc <= 0) return TRUE;
539     else if (argc >= 2) l = strlen(argv[1]);
540 
541     /* See if we're starting a new CIF style.  If not, make
542      * sure that the current (maybe default?) CIF style has
543      * a name.
544      */
545 
546     if (strcmp(argv[0], "style") == 0)
547     {
548 	if (argc != 2)
549 	{
550 	    if ((argc != 4) || (strncmp(argv[2], "variant", 7)))
551 	    {
552 		wrongNumArgs:
553 		TechError("Wrong number of arguments in %s statement.\n",
554 				argv[0]);
555 		errorReturn:
556 		if (newOp != NULL)
557 		    freeMagic((char *) newOp);
558 		return TRUE;
559 	    }
560 	}
561 	for (newStyle = CIFStyleList; newStyle != NULL;
562 		newStyle = newStyle->cs_next)
563 	{
564 	    /* Here we're only establishing existence;		*/
565 	    /* break on the first variant found.		*/
566 
567 	    if (!strncmp(newStyle->cs_name, argv[1], l))
568 		break;
569 	}
570 	if (newStyle == NULL)
571 	{
572 	    if (argc == 2)
573 	    {
574 		newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep));
575 		newStyle->cs_next = NULL;
576 		newStyle->cs_name = StrDup((char **) NULL, argv[1]);
577 
578 		/* Append to end of style list */
579 		if (CIFStyleList == NULL)
580 		    CIFStyleList = newStyle;
581 		else
582 		{
583 		    for (p = CIFStyleList; p->cs_next; p = p->cs_next);
584 		    p->cs_next = newStyle;
585 		}
586 	    }
587 	    else	/* Handle style variants */
588 	    {
589 		CIFKeep *saveStyle = NULL;
590 		char *tptr, *cptr;
591 
592 		/* 4th argument is a comma-separated list of variants.	*/
593 		/* In addition to the default name recorded above,	*/
594 		/* record each of the variants.				*/
595 
596 		tptr = argv[3];
597 		while (*tptr != '\0')
598 		{
599 		    cptr = strchr(tptr, ',');
600 		    if (cptr != NULL) *cptr = '\0';
601 		    newStyle = (CIFKeep *)mallocMagic(sizeof(CIFKeep));
602 		    newStyle->cs_next = NULL;
603 		    newStyle->cs_name = (char *)mallocMagic(l
604 				+ strlen(tptr) + 1);
605 		    sprintf(newStyle->cs_name, "%s%s", argv[1], tptr);
606 
607 		    /* Remember the first variant as the default */
608 		    if (saveStyle == NULL) saveStyle= newStyle;
609 
610 		    /* Append to end of style list */
611 		    if (CIFStyleList == NULL)
612 			CIFStyleList = newStyle;
613 		    else
614 		    {
615 			for (p = CIFStyleList; p->cs_next; p = p->cs_next);
616 			p->cs_next = newStyle;
617 		    }
618 
619 		    if (cptr == NULL)
620 			break;
621 		    else
622 			tptr = cptr + 1;
623 		}
624 		newStyle = saveStyle;
625 	    }
626 	}
627 
628 	if (CIFCurStyle == NULL)
629 	{
630 	    cifTechNewStyle();
631 	    CIFCurStyle->cs_name = newStyle->cs_name;
632 	    CIFCurStyle->cs_status = TECH_PENDING;
633 	}
634 	else if ((CIFCurStyle->cs_status == TECH_PENDING) ||
635 			(CIFCurStyle->cs_status == TECH_SUSPENDED))
636 	    CIFCurStyle->cs_status = TECH_LOADED;
637 	else if (CIFCurStyle->cs_status == TECH_NOT_LOADED)
638 	{
639 	    if (CIFCurStyle->cs_name == NULL)
640 		return (FALSE);
641 	    else if (argc == 2)
642 	    {
643 		if (!strcmp(argv[1], CIFCurStyle->cs_name))
644 		    CIFCurStyle->cs_status = TECH_PENDING;
645 	    }
646 	    else if (argc == 4)
647 	    {
648 		/* Verify that the style matches one variant */
649 
650 		char *tptr, *cptr;
651 
652 		if (!strncmp(CIFCurStyle->cs_name, argv[1], l))
653 		{
654 		    tptr = argv[3];
655 		    while (*tptr != '\0')
656 		    {
657 			cptr = strchr(tptr, ',');
658 			if (cptr != NULL) *cptr = '\0';
659 			if (!strcmp(CIFCurStyle->cs_name + l, tptr))
660 			{
661 			    CIFCurStyle->cs_status = TECH_PENDING;
662 			    return TRUE;
663 			}
664 			if (cptr == NULL)
665 			    return TRUE;
666 			else
667 			    tptr = cptr + 1;
668 		    }
669 		}
670 	    }
671 	}
672 	return (TRUE);
673     }
674 
675     /* Only continue past this point if we are loading the cif output style */
676     if (CIFCurStyle == NULL) return FALSE;
677     if ((CIFCurStyle->cs_status != TECH_PENDING) &&
678 		(CIFCurStyle->cs_status != TECH_SUSPENDED))
679 	return TRUE;
680 
681     /* Process scalefactor lines next. */
682 
683     if (strcmp(argv[0], "scalefactor") == 0)
684     {
685 	if ((argc < 2) || (argc > 4)) goto wrongNumArgs;
686 	CIFCurStyle->cs_scaleFactor = CIFParseScale(argv[1],
687 		&CIFCurStyle->cs_expander);
688 
689 	/*
690 	 * The "nanometers" keyword multiplies the expander by 10.
691 	 * Any reducer value and keyword "calmaonly" are now both ignored.
692 	 */
693 
694 	if (argc >= 3)
695 	{
696 	    if (strncmp(argv[argc - 1], "nanom", 5) == 0)
697 		CIFCurStyle->cs_expander *= 10;
698 	    else if (strncmp(argv[argc - 1], "angstr", 6) == 0)
699 		CIFCurStyle->cs_expander *= 100;
700 	}
701 
702 	CIFCurStyle->cs_reducer = 1;	/* initial value only */
703 
704 	if (CIFCurStyle->cs_scaleFactor <= 0)
705 	{
706 	    CIFCurStyle->cs_scaleFactor = 0;
707 	    TechError("Scalefactor must be a strictly positive value.\n");
708 	    goto errorReturn;
709 	}
710 	return TRUE;
711     }
712 
713     /* New for magic-7.3.100---allow GDS database units to be other	*/
714     /* than nanometers.  Really, there is only one option here, which	*/
715     /* is "units angstroms".   This option does not affect CIF output,	*/
716     /* whose units are fixed at centimicrons.				*/
717 
718     if (strcmp(argv[0], "units") == 0)
719     {
720 	if (argc != 2) goto wrongNumArgs;
721 	if (!strncmp(argv[1], "angstr", 6))
722 	    CIFCurStyle->cs_flags |= CWF_ANGSTROMS;
723 	return TRUE;
724     }
725 
726     if (strcmp(argv[0], "stepsize") == 0)
727     {
728 	if (argc != 2) goto wrongNumArgs;
729 	CIFCurStyle->cs_stepSize = atoi(argv[1]);
730 	if (CIFCurStyle->cs_stepSize <= 0)
731 	{
732 	    TechError("Step size must be positive integer.\n");
733 	    CIFCurStyle->cs_stepSize = 0;
734 	}
735 	return TRUE;
736     }
737 
738     /* Process "gridlimit" line next. */
739     if (strncmp(argv[0], "grid", 4) == 0)
740     {
741 	if (StrIsInt(argv[1]))
742 	{
743 	    CIFCurStyle->cs_gridLimit = atoi(argv[1]);
744 	    if (CIFCurStyle->cs_gridLimit < 0)
745 	    {
746 		TechError("Grid limit must be a positive integer.\n");
747 		CIFCurStyle->cs_gridLimit = 0;
748 	    }
749 	}
750 	else
751 	    TechError("Unable to parse grid limit value.\n");
752 
753 	return TRUE;
754     }
755 
756     /* Process "variant" lines next. */
757 
758     if (strncmp(argv[0], "variant", 7) == 0)
759     {
760 	int l;
761 	char *cptr, *tptr;
762 
763 	/* If our style variant is not one of the ones declared */
764 	/* on the line, then we ignore all input until we 	*/
765 	/* either reach the end of the style, the end of the	*/
766 	/* section, or another "variant" line.			*/
767 
768 	if (argc != 2) goto wrongNumArgs;
769 	tptr = argv[1];
770 	while (*tptr != '\0')
771 	{
772 	    cptr = strchr(tptr, ',');
773 	    if (cptr != NULL)
774 	    {
775 		*cptr = '\0';
776 		for (j = 1; isspace(*(cptr - j)); j++)
777 		    *(cptr - j) = '\0';
778 	    }
779 
780 	    if (*tptr == '*')
781 	    {
782 		CIFCurStyle->cs_status = TECH_PENDING;
783 		return TRUE;
784 	    }
785 	    else
786 	    {
787 		l = strlen(CIFCurStyle->cs_name) - strlen(tptr);
788 		if (!strcmp(tptr, CIFCurStyle->cs_name + l))
789 		{
790 		    CIFCurStyle->cs_status = TECH_PENDING;
791 		    return TRUE;
792 		}
793 	    }
794 
795 	    if (cptr == NULL)
796 		break;
797 	    else
798 		tptr = cptr + 1;
799 	}
800 	CIFCurStyle->cs_status = TECH_SUSPENDED;
801     }
802 
803     /* Anything below this line is not parsed if we're in TECH_SUSPENDED mode */
804     if (CIFCurStyle->cs_status != TECH_PENDING) return TRUE;
805 
806     newLayer = NULL;
807     if ((strcmp(argv[0], "templayer") == 0) || (strcmp(argv[0], "layer") == 0) ||
808 	(strcmp(argv[0], "labellayer") == 0))
809     {
810 	if (CIFCurStyle->cs_nLayers == MAXCIFLAYERS)
811 	{
812 	    cifCurLayer = NULL;
813 	    TechError("Can't handle more than %d CIF layers.\n", MAXCIFLAYERS);
814 	    TechError("Your local Magic wizard can fix this.\n");
815 	    goto errorReturn;
816 	}
817 	if (argc != 2 && argc != 3)
818 	{
819 	    cifCurLayer = NULL;
820 	    goto wrongNumArgs;
821 	}
822 	newLayer = CIFCurStyle->cs_layers[CIFCurStyle->cs_nLayers]
823 	    = (CIFLayer *) mallocMagic(sizeof(CIFLayer));
824 	CIFCurStyle->cs_nLayers += 1;
825 	if ((cifCurOp == NULL) && (cifCurLayer != NULL) && !cifGotLabels)
826 	{
827 	    TechError("Layer \"%s\" contains no material.\n",
828 		cifCurLayer->cl_name);
829 	}
830 	newLayer->cl_name = NULL;
831 	(void) StrDup(&newLayer->cl_name, argv[1]);
832 	newLayer->cl_ops = NULL;
833 	newLayer->cl_flags = 0;
834 	newLayer->cl_calmanum = newLayer->cl_calmatype = -1;
835 	newLayer->min_width = 0; /* for growSlivers */
836 #ifdef THREE_D
837 	newLayer->cl_height = 0.0;
838 	newLayer->cl_thick = 0.0;
839 	newLayer->cl_renderStyle = STYLE_PALEHIGHLIGHTS - TECHBEGINSTYLES;
840 #endif
841 	if (strcmp(argv[0], "templayer") == 0)
842 	    newLayer->cl_flags |= CIF_TEMP;
843 	else if (strcmp(argv[0], "labellayer") == 0)
844 	    newLayer->cl_flags |= CIF_LABEL;
845 	cifCurLayer = newLayer;
846 	cifCurOp = NULL;
847 	cifGotLabels = FALSE;
848 
849 	/* Handle a special case of a list of layer names on the layer
850 	 * line.  Turn them into an OR operation.
851 	 */
852 
853 	if (argc == 3)
854 	{
855 	    cifCurOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
856 	    cifCurOp->co_opcode = CIFOP_OR;
857 	    cifParseLayers(argv[2], CIFCurStyle, &cifCurOp->co_paintMask,
858 		&cifCurOp->co_cifMask, FALSE);
859 	    cifCurOp->co_distance = 0;
860 	    cifCurOp->co_next = NULL;
861 	    cifCurOp->co_client = (ClientData)NULL;
862 	    cifCurLayer->cl_ops = cifCurOp;
863 	}
864 	return TRUE;
865     }
866 
867     if (strcmp(argv[0], "labels") == 0)
868     {
869 	bool portOnly = FALSE, noPort = FALSE;
870 
871 	if (cifCurLayer == NULL)
872 	{
873 	    TechError("Must define layer before giving labels it holds.\n");
874 	    goto errorReturn;
875 	}
876 	if (cifCurLayer->cl_flags & CIF_TEMP)
877 	    TechError("Why are you attaching labels to a temporary layer?\n");
878 	if (argc == 3)
879 	{
880 	    if (!strncmp(argv[2], "port", 4))
881 		portOnly = TRUE;
882 	    else if (!strncmp(argv[2], "noport", 6))
883 		noPort = TRUE;
884 	    else
885 	    {
886 		TechError("Unknown option %s for labels statement.\n", argv[2]);
887 		goto wrongNumArgs;
888 	    }
889 	}
890 	else if (argc != 2) goto wrongNumArgs;
891 	DBTechNoisyNameMask(argv[1], &mask);
892 	for (i=0; i<TT_MAXTYPES; i+=1)
893 	{
894 	    if (TTMaskHasType(&mask, i))
895 	    {
896 		if (portOnly != TRUE)
897 		    CIFCurStyle->cs_labelLayer[i] = CIFCurStyle->cs_nLayers-1;
898 		if (noPort != TRUE)
899 		    CIFCurStyle->cs_portLayer[i] = CIFCurStyle->cs_nLayers-1;
900 	    }
901 	}
902 	cifGotLabels = TRUE;
903 	return TRUE;
904     }
905 
906     if ((strcmp(argv[0], "calma") == 0) || (strncmp(argv[0], "gds", 3) == 0))
907     {
908 	if (cifCurLayer == NULL)
909 	{
910 	    TechError("Must define layers before giving their Calma types.\n");
911 	    goto errorReturn;
912 	}
913 	if (cifCurLayer->cl_flags & CIF_TEMP)
914 	    TechError("Why assign a Calma number to a temporary layer?\n");
915 	if (argc != 3) goto wrongNumArgs;
916 	if (!cifCheckCalmaNum(argv[1]) || !cifCheckCalmaNum(argv[2]))
917 	    TechError("Calma layer and type numbers must be 0 to %d.\n",
918 		CALMA_LAYER_MAX);
919 	cifCurLayer->cl_calmanum = atoi(argv[1]);
920 	cifCurLayer->cl_calmatype = atoi(argv[2]);
921 	return TRUE;
922     }
923     if (strcmp(argv[0], "min-width") == 0) /* used in growSliver */
924     {
925 	if (cifCurLayer == NULL)
926 	{
927 	    TechError("Must define layers before assigning a minimum width.\n");
928 	    goto errorReturn;
929 	}
930 	if (argc != 2) goto wrongNumArgs;
931 	cifCurLayer->min_width = atoi(argv[1]);
932 	CIFCurStyle->cs_flags |= CWF_GROW_SLIVERS;
933 	return TRUE;
934     }
935 
936     if (strcmp(argv[0], "render") == 0) /* used by specialopen wind3d client */
937     {
938 #ifdef THREE_D
939 	float height, thick;
940 	int i, style, lcnt;
941 	CIFLayer *layer;
942 
943 	if (argc != 5) goto wrongNumArgs;
944 
945 	cifCurLayer = NULL;	/* This is not in a layer definition */
946 
947 	style = DBWTechParseStyle(argv[2]);
948 	if (style < 0)
949 	{
950 	    TechError("Error:  Bad render style for CIF layer.\n");
951 	    goto errorReturn;
952 	}
953 
954 	if (!StrIsNumeric(argv[3]) || !StrIsNumeric(argv[4]))
955 	{
956 	    TechError("Syntax: render <layer> <style> <height> <thick>\n");
957 	    goto errorReturn;
958 	}
959 	height = (float)atof(argv[3]);
960 	thick = (float)atof(argv[4]);
961 
962 	lcnt = 0;
963 	for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
964 	{
965 	    layer = CIFCurStyle->cs_layers[i];
966 	    if (!strcmp(argv[1], layer->cl_name))
967 	    {
968 		layer->cl_height = height;
969 		layer->cl_thick = thick;
970 		layer->cl_renderStyle = style;
971 		lcnt++;
972 	    }
973 	}
974 	if (lcnt == 0)
975 	{
976 	    TechError("Unknown layer name.\n");
977 	    goto errorReturn;
978 	}
979 #endif
980         return TRUE;
981     }
982 
983     /*
984      * miscellaneous cif/calma-writing boolean options
985      */
986 
987     if (strcmp(argv[0], "options") == 0)
988     {
989 	int i;
990 	if (argc < 2) goto wrongNumArgs;
991 	for (i = 1; i < argc; i++)
992 	{
993 	    if (strcmp(argv[i], "calma-permissive-labels") == 0)
994 		CIFCurStyle->cs_flags |= CWF_PERMISSIVE_LABELS;
995 	    else if (strcmp(argv[i], "grow-euclidean") == 0)
996 		CIFCurStyle->cs_flags |= CWF_GROW_EUCLIDEAN;
997 	    else if (strcmp(argv[i], "see-no-vendor") == 0)
998 		CIFCurStyle->cs_flags |= CWF_SEE_NO_VENDOR;
999 	    else if (strcmp(argv[i], "no-errors") == 0)
1000 		CIFCurStyle->cs_flags |= CWF_NO_ERRORS;
1001 	    else if (strcmp(argv[i], "string-limit") == 0)
1002 		CIFCurStyle->cs_flags |= CWF_STRING_LIMIT;
1003 	}
1004 	return TRUE;
1005     }
1006 
1007     /* Anything below here is a geometric operation, so we can
1008      * do some set-up that is common to all the operations.
1009      */
1010 
1011     if (cifCurLayer == NULL)
1012     {
1013 	TechError("Must define layer before specifying operation.\n");
1014 	goto errorReturn;
1015     }
1016     newOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
1017     TTMaskZero(&newOp->co_paintMask);
1018     TTMaskZero(&newOp->co_cifMask);
1019     newOp->co_opcode = 0;
1020     newOp->co_distance = 0;
1021     newOp->co_next = NULL;
1022     newOp->co_client = (ClientData)NULL;
1023 
1024     if (strcmp(argv[0], "and") == 0)
1025 	newOp->co_opcode = CIFOP_AND;
1026     else if (strcmp(argv[0], "and-not") == 0)
1027 	newOp->co_opcode = CIFOP_ANDNOT;
1028     else if (strcmp(argv[0], "or") == 0)
1029 	newOp->co_opcode = CIFOP_OR;
1030     else if (strcmp(argv[0], "grow") == 0)
1031 	newOp->co_opcode = CIFOP_GROW;
1032     else if (strcmp(argv[0], "grow-min") == 0)
1033 	newOp->co_opcode = CIFOP_GROWMIN;
1034     else if (strcmp(argv[0], "grow-grid") == 0)
1035 	newOp->co_opcode = CIFOP_GROW_G;
1036     else if (strcmp(argv[0], "shrink") == 0)
1037 	newOp->co_opcode = CIFOP_SHRINK;
1038     else if (strcmp(argv[0], "bloat-or") == 0)
1039 	newOp->co_opcode = CIFOP_BLOAT;
1040     else if (strcmp(argv[0], "bloat-max") == 0)
1041 	newOp->co_opcode = CIFOP_BLOATMAX;
1042     else if (strcmp(argv[0], "bloat-min") == 0)
1043 	newOp->co_opcode = CIFOP_BLOATMIN;
1044     else if (strcmp(argv[0], "bloat-all") == 0)
1045 	newOp->co_opcode = CIFOP_BLOATALL;
1046     else if (strcmp(argv[0], "squares") == 0)
1047 	newOp->co_opcode = CIFOP_SQUARES;
1048     else if (strcmp(argv[0], "squares-grid") == 0)
1049 	newOp->co_opcode = CIFOP_SQUARES_G;
1050     else if (strcmp(argv[0], "slots") == 0)
1051 	newOp->co_opcode = CIFOP_SLOTS;
1052     else if (strcmp(argv[0], "bbox") == 0)
1053 	newOp->co_opcode = CIFOP_BBOX;
1054     else if (strcmp(argv[0], "net") == 0)
1055 	newOp->co_opcode = CIFOP_NET;
1056     else if (strcmp(argv[0], "maxrect") == 0)
1057 	newOp->co_opcode = CIFOP_MAXRECT;
1058     else if (strcmp(argv[0], "boundary") == 0)
1059 	newOp->co_opcode = CIFOP_BOUNDARY;
1060     else if (strcmp(argv[0], "mask-hints") == 0)
1061 	newOp->co_opcode = CIFOP_MASKHINTS;
1062     else if (strcmp(argv[0], "close") == 0)
1063 	newOp->co_opcode = CIFOP_CLOSE;
1064     else if (strcmp(argv[0], "bridge") == 0)
1065 	newOp->co_opcode = CIFOP_BRIDGE;
1066     else if (strcmp(argv[0], "bridge-lim") == 0)
1067 	newOp->co_opcode = CIFOP_BRIDGELIM;
1068     else
1069     {
1070 	TechError("Unknown statement \"%s\".\n", argv[0]);
1071 	goto errorReturn;
1072     }
1073 
1074     switch (newOp->co_opcode)
1075     {
1076 	case CIFOP_AND:
1077 	case CIFOP_ANDNOT:
1078 	case CIFOP_OR:
1079 	    if (argc != 2) goto wrongNumArgs;
1080 	    cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1081 		&newOp->co_cifMask,FALSE);
1082 	    break;
1083 
1084 	case CIFOP_GROW:
1085 	case CIFOP_GROWMIN:
1086 	case CIFOP_GROW_G:
1087 	case CIFOP_SHRINK:
1088 	case CIFOP_CLOSE:
1089 	    if (argc != 2) goto wrongNumArgs;
1090 	    newOp->co_distance = atoi(argv[1]);
1091 	    if (newOp->co_distance <= 0)
1092 	    {
1093 		TechError("Grow/shrink distance must be greater than zero.\n");
1094 		goto errorReturn;
1095 	    }
1096 	    break;
1097 
1098 	case CIFOP_BRIDGE:
1099 	    if (argc != 3) goto wrongNumArgs;
1100 	    newOp->co_distance = atoi(argv[1]);
1101 	    if (newOp->co_distance <= 0)
1102 	    {
1103 		TechError("Bridge distance must be greater than zero.\n");
1104 		goto errorReturn;
1105 	    }
1106 	    bridge = (BridgeData *)mallocMagic(sizeof(BridgeData));
1107 	    bridge->br_width = atoi(argv[2]);
1108 	    if (bridge->br_width <= 0)
1109 	    {
1110 		TechError("Bridge width must be greater than zero.\n");
1111 		freeMagic(bridge);
1112 		goto errorReturn;
1113 	    }
1114 	    newOp->co_client = (ClientData)bridge;
1115 	    break;
1116 
1117 	case CIFOP_BRIDGELIM:
1118 	    if (argc != 4) goto wrongNumArgs;
1119 	    newOp->co_distance = atoi(argv[1]);
1120 	    if (newOp->co_distance <= 0)
1121 	    {
1122 		TechError("Bridge distance must be greater than zero.\n");
1123 		goto errorReturn;
1124 	    }
1125 	    bridge = (BridgeData *)mallocMagic(sizeof(BridgeData));
1126 	    bridge->br_width = atoi(argv[2]);
1127 	    if (bridge->br_width <= 0)
1128 	    {
1129 		TechError("Bridge width must be greater than zero.\n");
1130 		freeMagic(bridge);
1131 		goto errorReturn;
1132 	    }
1133 	    cifParseLayers(argv[3], CIFCurStyle, &newOp->co_paintMask, &newOp->co_cifMask,FALSE);
1134 	    newOp->co_client = (ClientData)bridge;
1135 	    break;
1136 
1137 	case CIFOP_BLOATALL:
1138 	    if (argc != 3) goto wrongNumArgs;
1139 	    cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1140 			&newOp->co_cifMask, FALSE);
1141 	    bloats = (BloatData *)mallocMagic(sizeof(BloatData));
1142 	    for (i = 0; i < TT_MAXTYPES; i++)
1143 		bloats->bl_distance[i] = 0;
1144 	    newOp->co_client = (ClientData)bloats;
1145 	    cifParseLayers(argv[2], CIFCurStyle, &mask, &cifMask, TRUE);
1146 
1147 	    /* 5/25/2020:  Lifting restriction that bloatLayers types	*/
1148 	    /* cannot be CIF or temp layers.  However, CIF/temp layers	*/
1149 	    /* and magic database layers may not be mixed.		*/
1150 
1151 	    if (!TTMaskIsZero(&mask) && !TTMaskIsZero(&cifMask))
1152 		TechError("Can't mix CIF and magic layers in bloat statement.\n");
1153 
1154 	    /* 10/15/2019:  Lifting restriction that the types that	*/
1155 	    /* trigger the bloating must be in the same plane as the	*/
1156 	    /* types that are bloated into.				*/
1157 
1158 	    TTMaskZero(&bloatLayers);
1159 	    if (!TTMaskIsZero(&mask))
1160 	    {
1161 		TTMaskSetMask(&bloatLayers, &mask);
1162 		for (i = 0; i < TT_MAXTYPES;  i++)
1163 		    if (TTMaskHasType(&mask, i))
1164 			bloats->bl_distance[i] = 1;
1165 
1166 		goto bloatCheck;
1167 	    }
1168 	    else
1169 	    {
1170 		TTMaskSetMask(&bloatLayers, &cifMask);
1171 		for (i = 0; i < TT_MAXTYPES;  i++)
1172 		    if (TTMaskHasType(&cifMask, i))
1173 			bloats->bl_distance[i] = 1;
1174 
1175 		bloats->bl_plane = -1;	/* Indicates CIF types */
1176 	    }
1177 	    break;
1178 
1179 	case CIFOP_BLOAT:
1180 	case CIFOP_BLOATMIN:
1181 	case CIFOP_BLOATMAX:
1182 	    if (argc < 4) goto wrongNumArgs;
1183 	    cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
1184 		    (TileTypeBitMask *)NULL, FALSE);
1185 	    argc -= 2;
1186 	    bloatArg = argv + 2;
1187 	    bloatLayers = newOp->co_paintMask;
1188 	    bloats = (BloatData *)mallocMagic(sizeof(BloatData));
1189 	    for (i = 0; i < TT_MAXTYPES; i++)
1190 		bloats->bl_distance[i] = 0;
1191 	    newOp->co_client = (ClientData)bloats;
1192 
1193 	    while (argc > 0)
1194 	    {
1195 		if (argc == 1) goto wrongNumArgs;
1196 		if (strcmp(*bloatArg, "*") == 0)
1197 		{
1198 		    mask = DBAllTypeBits;
1199 		    tempMask = DBZeroTypeBits;
1200 		}
1201 		else
1202 		{
1203 		    cifParseLayers(*bloatArg, CIFCurStyle, &mask, &tempMask, TRUE);
1204 		    TTMaskSetMask(&bloatLayers, &mask);
1205 		}
1206 		if (!TTMaskEqual(&tempMask, &DBZeroTypeBits))
1207 		    TechError("Can't use templayers in bloat statement.\n");
1208 
1209 		distance = atoi(bloatArg[1]);
1210 		if ((distance < 0) && (newOp->co_opcode == CIFOP_BLOAT))
1211 		{
1212 		    TechError("Bloat-or distances must not be negative.\n");
1213 		    distance = 0;
1214 		}
1215 		for (i = 0; i < TT_MAXTYPES;  i++)
1216 		    if (TTMaskHasType(&mask, i))
1217 			bloats->bl_distance[i] = distance;
1218 
1219 		argc -= 2;
1220 		bloatArg += 2;
1221 	    }
1222 
1223 bloatCheck:
1224 	    /* Don't do any bloating at boundaries between tiles of the
1225 	     * types being bloated.  Otherwise a bloat could pass right
1226 	     * through a skinny tile and out the other side.
1227 	     */
1228 	    for (i = 0; i < TT_MAXTYPES; i++)
1229 		if (TTMaskHasType(&newOp->co_paintMask, i))
1230 		    bloats->bl_distance[i] = 0;
1231 
1232 	    /* Make sure that all the layers specified in the statement
1233 	     * fall in a single plane.
1234 	     */
1235 
1236 	    for (i = 0; i < PL_MAXTYPES; i++)
1237 	    {
1238 		tempMask = bloatLayers;
1239 		TTMaskAndMask(&tempMask, &DBPlaneTypes[i]);
1240 		if (TTMaskEqual(&tempMask, &bloatLayers)) {
1241 		    bloats->bl_plane = i;
1242 		    goto bloatDone;
1243 		}
1244 	    }
1245 	    TechError("Not all bloat layers fall in the same plane.\n");
1246 	    bloats->bl_plane = 0;   /* Prevents magic from segfaulting */
1247 	    bloatDone: break;
1248 
1249 	case CIFOP_NET:
1250 	    if (argc != 3) goto wrongNumArgs;
1251 	    newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
1252 	    cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
1253 		&newOp->co_cifMask, FALSE);
1254 	    break;
1255 
1256 	case CIFOP_MASKHINTS:
1257 	    if (argc != 2) goto wrongNumArgs;
1258 	    newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
1259 	    break;
1260 
1261 	case CIFOP_MAXRECT:
1262 	    if (argc == 2)
1263 	    {
1264 		if (!strncmp(argv[1], "ext", 3))
1265 		    newOp->co_client = (ClientData)1;
1266 		else if (strncmp(argv[1], "int", 3))
1267 		    TechError("Maxrect takes only one optional argument "
1268 				"\"external\" or \"internal\" (default).\n");
1269 	    }
1270 	    else if (argc != 1)
1271 		goto wrongNumArgs;
1272 	    break;
1273 
1274 	case CIFOP_BBOX:
1275 	    if (argc == 2)
1276 	    {
1277 		if (!strcmp(argv[1], "top"))
1278 		    newOp->co_client = (ClientData)1;
1279 		else
1280 		    TechError("BBox takes only one optional argument \"top\".\n");
1281 	    }
1282 	    else if (argc != 1)
1283 		goto wrongNumArgs;
1284 	    break;
1285 
1286 	case CIFOP_BOUNDARY:
1287 	    /* CIFOP_BOUNDARY has no arguments */
1288 	    if (argc != 1)
1289 		goto wrongNumArgs;
1290 	    break;
1291 
1292 	case CIFOP_SQUARES_G:
1293 	case CIFOP_SQUARES:
1294 
1295 	    squares = (SquaresData *)mallocMagic(sizeof(SquaresData));
1296 	    newOp->co_client = (ClientData)squares;
1297 
1298 	    if (argc == 2)
1299 	    {
1300 		i = atoi(argv[1]);
1301 		squares->sq_border = atoi(argv[1]);
1302 		if ((i <= 0) || (i & 1))
1303 		{
1304 		    TechError("Squares must have positive even sizes.\n");
1305 		    goto errorReturn;
1306 		}
1307 		squares->sq_border = i/2;
1308 		squares->sq_size = i;
1309 		squares->sq_sep = i;
1310 		squares->sq_gridx = 1; /* set default grid */
1311 		squares->sq_gridy = 1; /* set default grid */
1312 	    }
1313 	    else if (argc == 4 || ((argc == 5 || argc == 6)
1314 			&& newOp->co_opcode==CIFOP_SQUARES_G))
1315 	    {
1316 		squares->sq_border = atoi(argv[1]);
1317 		if (squares->sq_border < 0)
1318 		{
1319 		    TechError("Square border must not be negative.\n");
1320 		    goto errorReturn;
1321 		}
1322 		squares->sq_size = atoi(argv[2]);
1323 		if (squares->sq_size <= 0)
1324 		{
1325 		    TechError("Squares must have positive sizes.\n");
1326 		    goto errorReturn;
1327 		}
1328 		squares->sq_sep = atoi(argv[3]);
1329 		if (squares->sq_sep <= 0)
1330 		{
1331 		    TechError("Square separation must be positive.\n");
1332 		    goto errorReturn;
1333 		}
1334 		if (argc >= 5)
1335 		{
1336 		    squares->sq_gridx = squares->sq_gridy = atoi(argv[4]);
1337 		    if (squares->sq_gridx <= 0)
1338 		    {
1339 		        TechError("Square grid must be strictly positive.\n");
1340 			squares->sq_gridx = squares->sq_gridy = 1;
1341 		        goto errorReturn;
1342 		    }
1343 		}
1344 		else
1345 		{
1346 		    squares->sq_gridx = 1; /* set default grid */
1347 		    squares->sq_gridy = 1; /* set default grid */
1348 		}
1349 		if (argc == 6)
1350 		{
1351 		    squares->sq_gridy = atoi(argv[5]);
1352 		    if (squares->sq_gridy <= 0)
1353 		    {
1354 		        TechError("Square y-grid must be strictly positive.\n");
1355 			squares->sq_gridy = 1;
1356 		        goto errorReturn;
1357 		    }
1358 		}
1359 	    }
1360 	    else goto wrongNumArgs;
1361 
1362 	    /* Ensure that squares are never placed at less than the	*/
1363 	    /* minimum allowed mask resolution.  This may require that	*/
1364 	    /* operation "squares" be changed to "squares-grid".	*/
1365 
1366 	    if (squares->sq_gridx < CIFCurStyle->cs_gridLimit)
1367 	    {
1368 		squares->sq_gridx = CIFCurStyle->cs_gridLimit;
1369 		newOp->co_opcode = CIFOP_SQUARES_G;
1370 	    }
1371 	    if (squares->sq_gridy < CIFCurStyle->cs_gridLimit)
1372 	    {
1373 		squares->sq_gridy = CIFCurStyle->cs_gridLimit;
1374 		newOp->co_opcode = CIFOP_SQUARES_G;
1375 	    }
1376 	    break;
1377 
1378 	case CIFOP_SLOTS:
1379 
1380 	    slots = (SlotsData *)mallocMagic(sizeof(SlotsData));
1381 	    newOp->co_client = (ClientData)slots;
1382 
1383 	    if (argc >= 4)
1384 	    {
1385 		i = atoi(argv[1]);
1386 		slots->sl_sborder = i;
1387 		if (i < 0)
1388 		{
1389 		    TechError("Slot border must be non-negative.\n");
1390 		    goto errorReturn;
1391 		}
1392 		i = atoi(argv[2]);
1393 		slots->sl_ssize = i;
1394 		if (i <= 0)
1395 		{
1396 		    TechError("Slot short-side size must be strictly positive.\n");
1397 		    goto errorReturn;
1398 		}
1399 		i = atoi(argv[3]);
1400 		slots->sl_ssep = i;
1401 		if (i <= 0)
1402 		{
1403 		    TechError("Slot separation must be strictly positive.\n");
1404 		    goto errorReturn;
1405 		}
1406 		/* Initialize other values, in case they are not specified */
1407 		slots->sl_lborder = 0;
1408 		slots->sl_lsize = 0;
1409 		slots->sl_lsep = 0;
1410 		slots->sl_offset = 0;
1411 		slots->sl_start = 0;
1412 	    }
1413 	    if (argc >= 5)
1414 	    {
1415 		i = atoi(argv[4]);
1416 		slots->sl_lborder = i;
1417 		if (i < 0)
1418 		{
1419 		    TechError("Slot border must be non-negative.\n");
1420 		    goto errorReturn;
1421 		}
1422 	    }
1423 	    if (argc >= 6)
1424 	    {
1425 		i = atoi(argv[5]);
1426 		slots->sl_lsize = i;
1427 		if (i < 0)
1428 		{
1429 		    TechError("Slot long-side size must be positive or zero.\n");
1430 		    goto errorReturn;
1431 		}
1432 		i = atoi(argv[6]);
1433 		slots->sl_lsep = i;
1434 		if (i < 0)
1435 		{
1436 		    TechError("Slot long-side separation must be non-negative.\n");
1437 		    goto errorReturn;
1438 		}
1439 		else if (i == 0 && (slots->sl_lsize > 0))
1440 		{
1441 		    TechError("Slot long-side separation must be strictly positive"
1442 				" when long-side size is nonzero\n");
1443 		    goto errorReturn;
1444 		}
1445 	    }
1446 	    if (argc >= 8)
1447 	    {
1448 		i = atoi(argv[7]);
1449 		slots->sl_offset = i;
1450 		if (i < 0)
1451 		{
1452 		    TechError("Slot offset must be non-negative.\n");
1453 		    goto errorReturn;
1454 		}
1455 	    }
1456 	    if (argc == 9)
1457 	    {
1458 		i = atoi(argv[8]);
1459 		slots->sl_start = i;
1460 		if (i < 0)
1461 		{
1462 		    TechError("Slot start must be non-negative.\n");
1463 		    goto errorReturn;
1464 		}
1465 	    }
1466 	    if ((argc < 4) || (argc == 6) || (argc > 9))
1467 		goto wrongNumArgs;
1468 	    break;
1469     }
1470 
1471     /* Link the new CIFOp into the list. */
1472 
1473     if (cifCurOp == NULL)
1474 	cifCurLayer->cl_ops = newOp;
1475     else
1476 	cifCurOp->co_next = newOp;
1477     cifCurOp = newOp;
1478 
1479     return TRUE;
1480 }
1481 
1482 /*
1483  * ----------------------------------------------------------------------------
1484  *
1485  * cifCheckCalmaNum --
1486  *
1487  * 	This local procedure checks whether its argument is the ASCII
1488  *	representation of a positive integer between 0 and CALMA_LAYER_MAX.
1489  *
1490  * Results:
1491  *	TRUE if the argument string is valid as described above, FALSE if not.
1492  *
1493  * Side effects:
1494  *	None.
1495  *
1496  * ----------------------------------------------------------------------------
1497  */
1498 
1499 bool
cifCheckCalmaNum(str)1500 cifCheckCalmaNum(str)
1501     char *str;
1502 {
1503     int n = atoi(str);
1504 
1505     if (n < 0 || n > CALMA_LAYER_MAX)
1506 	return (FALSE);
1507 
1508     while (*str) {
1509 	char ch = *str++;
1510 	if (ch < '0' || ch > '9')
1511 	    return (FALSE);
1512     }
1513 
1514     return (TRUE);
1515 }
1516 
1517 /*
1518  * ----------------------------------------------------------------------------
1519  *
1520  * cifComputeRadii --
1521  *
1522  * 	This local procedure computes and fills in the grow and
1523  *	shrink distances for a layer.  Before calling this procedure,
1524  *	the distances must have been computed for all temporary
1525  *	layers used by this layer.
1526  *
1527  * Results:
1528  *	None.
1529  *
1530  * Side effects:
1531  *	Modifies cl_growDist and cl_shrinkDist in layer.
1532  *
1533  * ----------------------------------------------------------------------------
1534  */
1535 
1536 void
cifComputeRadii(layer,des)1537 cifComputeRadii(layer, des)
1538     CIFLayer *layer;		/* Layer for which to compute distances. */
1539     CIFStyle *des;		/* CIF style (used to find temp layer
1540 				 * distances.
1541 				 */
1542 {
1543     int i, grow, shrink, curGrow, curShrink;
1544     CIFOp *op;
1545     BloatData *bloats;
1546 
1547     grow = shrink = 0;
1548 
1549     for (op = layer->cl_ops; op != NULL; op = op->co_next)
1550     {
1551 	/* BBOX, NET, and MASKHINTS operators should never be used	*/
1552 	/* hierarchically so ignore any grow/shrink operators that	*/
1553 	/* come after them.						*/
1554 
1555 	if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET ||
1556 		    op->co_opcode == CIFOP_MASKHINTS)
1557 	    break;
1558 
1559 	/* If CIF layers are used, switch to the max of current
1560 	 * distances and those of the layers used.
1561 	 */
1562 
1563 	if (!TTMaskEqual(&op->co_cifMask, &DBZeroTypeBits))
1564 	{
1565 	    for (i=0; i < des->cs_nLayers; i++)
1566 	    {
1567 		if (TTMaskHasType(&op->co_cifMask, i))
1568 		{
1569 		    if (des->cs_layers[i]->cl_growDist > grow)
1570 			grow = des->cs_layers[i]->cl_growDist;
1571 		    if (des->cs_layers[i]->cl_shrinkDist > shrink)
1572 			shrink = des->cs_layers[i]->cl_shrinkDist;
1573 		}
1574 	    }
1575 	}
1576 
1577 	/* Add in grows and shrinks at this step. */
1578 
1579 	switch (op->co_opcode)
1580 	{
1581 	    case CIFOP_AND:
1582 	    case CIFOP_ANDNOT:
1583 	    case CIFOP_OR:
1584 	    case CIFOP_MASKHINTS:
1585 		break;
1586 
1587 	    case CIFOP_GROW:
1588 	    case CIFOP_GROWMIN:
1589 	    case CIFOP_GROW_G:
1590 		grow += op->co_distance;
1591 		break;
1592 
1593 	    case CIFOP_SHRINK:
1594 		shrink += op->co_distance;
1595 		break;
1596 
1597 	    /* For bloats use the largest distances (negative values are
1598 	     * for shrinks).
1599 	     */
1600 
1601 	    case CIFOP_BLOAT:
1602 		curGrow = curShrink = 0;
1603 		bloats = (BloatData *)op->co_client;
1604 		for (i = 0; i < TT_MAXTYPES; i++)
1605 		{
1606 		    if (bloats->bl_distance[i] > curGrow)
1607 			curGrow = bloats->bl_distance[i];
1608 		    else if ((-bloats->bl_distance[i]) > curShrink)
1609 			curShrink = -bloats->bl_distance[i];
1610 		}
1611 		grow += curGrow;
1612 		shrink += curShrink;
1613 		break;
1614 
1615 	    case CIFOP_BRIDGE: break;
1616 	    case CIFOP_BRIDGELIM: break;
1617 	    case CIFOP_SQUARES: break;
1618 	    case CIFOP_SQUARES_G: break;
1619 
1620 	}
1621     }
1622 
1623     layer->cl_growDist = grow;
1624     layer->cl_shrinkDist = shrink;
1625 
1626     /* TxPrintf("Radii for %s: grow %d, shrink %d.\n", layer->cl_name,
1627 	grow, shrink);
1628      */
1629 }
1630 
1631 /*
1632  * ----------------------------------------------------------------------------
1633  *
1634  * cifComputeHalo --
1635  *
1636  * Compute grow and shrink distances for each layer, and remember the
1637  * largest.  Convert from CIF/GDS to Magic internal dimensions.
1638  *
1639  * Results:  None.
1640  * Side effects:  Sets cs_radius value in the current cifoutput style.
1641  * ----------------------------------------------------------------------------
1642  */
1643 
1644 void
cifComputeHalo(style)1645 cifComputeHalo(style)
1646     CIFStyle *style;
1647 {
1648     int maxGrow, maxShrink, i;
1649 
1650     maxGrow = maxShrink = 0;
1651     for (i = 0; i < style->cs_nLayers; i++)
1652     {
1653 	cifComputeRadii(style->cs_layers[i], style);
1654 	if (style->cs_layers[i]->cl_growDist > maxGrow)
1655 	    maxGrow = style->cs_layers[i]->cl_growDist;
1656 	if (style->cs_layers[i]->cl_shrinkDist > maxShrink)
1657 	    maxShrink = style->cs_layers[i]->cl_shrinkDist;
1658     }
1659     if (maxGrow > maxShrink)
1660 	style->cs_radius = 2*maxGrow;
1661     else style->cs_radius = 2*maxShrink;
1662     style->cs_radius /= style->cs_scaleFactor;
1663     style->cs_radius++;
1664 
1665     /* TxPrintf("Radius for %s CIF is %d.\n",
1666      *  style->cs_name, style->cs_radius);
1667      */
1668 }
1669 
1670 
1671 /*
1672  * ----------------------------------------------------------------------------
1673  *
1674  * CIFTechFinal --
1675  *
1676  * 	This procedure is invoked after all the lines of a technology
1677  *	file have been read.  It checks to make sure that the
1678  *	section ended at a consistent point, and computes the interaction
1679  *	distances for hierarchical CIF processing.
1680  *
1681  * Results:
1682  *	None.
1683  *
1684  * Side effects:
1685  *	Error messages are output if there's incomplete stuff left.
1686  *	Interaction distances get computed for each CIF style
1687  *	in two steps.  First, for each layer the total grow and
1688  *	shrink distances are computed.	These are the maximum distances
1689  *	that edges may move because of grows and shrinks in creating
1690  *	the layer.  Second, the	radius for the style is computed.
1691  *	The radius is used in two ways: first to determine how far
1692  *	apart two subcells may be and still interact during CIF
1693  *	generation;  and second, to see how much material to yank in
1694  *	order to find all additional CIF resulting from interactions.
1695  *	Right now, a conservative approach is used:  use the greater
1696  *	of twice the largest grow distance or twice the largest shrink
1697  *	distance for both.  Twice the grow distance must be considered
1698  *	because two pieces of material may each grow towards the other
1699  *	and interact in the middle.  Twice the largest shrink distance
1700  *	is needed because subcells considered individually may each
1701  *	shrink away from a boundary where they touch;  the parent must
1702  *	fill in the gap.  To do this, it must include 2S additional
1703  *	material:  S is the size of the gap that must be filled, but
1704  *	its outside edge will shrink in by S, so we must start with
1705  *	2S material to have S left after the shrink.  Finally, one extra
1706  *	unit gets added because two pieces of material one radius apart
1707  *	can interact:  to find all this material we must look one unit
1708  *	farther out for anything overlapping (the search routines only
1709  *	look for overlapping material and ignore abutting material).
1710  *
1711  * ----------------------------------------------------------------------------
1712  */
1713 
1714 void
CIFTechFinal()1715 CIFTechFinal()
1716 {
1717     CIFStyle *style = CIFCurStyle;
1718     CIFOp *op;
1719     int i, minReduce;
1720 
1721     /* Allow the case where there's no CIF at all.  This is indicated
1722      * by a NULL CIFCurStyle.
1723      */
1724 
1725     if (!style) return;
1726 
1727     if ((cifCurLayer != NULL) && (cifCurOp == NULL) && !cifGotLabels)
1728     {
1729 	TechError("Layer \"%s\" contains no material.\n",
1730 	    cifCurLayer->cl_name);
1731     }
1732     cifCurLayer = NULL;
1733 
1734     /*
1735      * If cs_expander > 1, then all CIF op values must be scaled accordingly.
1736      * This routine loops through all CIF output styles.
1737      */
1738 
1739     CIFTechOutputScale(1, 1);
1740 
1741     if (style->cs_scaleFactor <= 0)
1742     {
1743 	TechError("No valid scale factor was given for %s CIF.\n",
1744 		style->cs_name);
1745 	style->cs_scaleFactor = 1;
1746 	return;
1747     }
1748 
1749     /*
1750      * Make sure that all contact layers include stacked contact types
1751      */
1752     for (i = 0; i < style->cs_nLayers; i++)
1753 	for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
1754 	{
1755 	    TileType d, s;
1756 	    TileTypeBitMask *rMask;
1757 
1758 	    for (d = TT_TECHDEPBASE; d < DBNumUserLayers; d++)
1759 		if (TTMaskHasType(&op->co_paintMask, d) && DBIsContact(d))
1760 		    for (s = DBNumUserLayers; s < DBNumTypes; s++)
1761 		    {
1762 			rMask = DBResidueMask(s);
1763 			if (TTMaskHasType(rMask, d))
1764 			    TTMaskSetType(&op->co_paintMask, s);
1765 		    }
1766 	}
1767 
1768     /*
1769      * Find the largest reducer value which divides into all of the CIF values.
1770      */
1771 
1772     minReduce = style->cs_scaleFactor;
1773     for (i = 0; i < style->cs_nLayers; i++)
1774     {
1775 	for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
1776 	{
1777 	    int j, c, bvalue;
1778 	    if (op->co_distance > 0)
1779 	    {
1780 		c = FindGCF(style->cs_scaleFactor, op->co_distance);
1781 		if (c < minReduce) minReduce = c;
1782 	    }
1783 	    if (op->co_client)
1784 	    {
1785 		BloatData *bloats;
1786 		BridgeData *bridge;
1787 		SquaresData *squares;
1788 		SlotsData *slots;
1789 		if (op->co_opcode == CIFOP_SLOTS)
1790 		{
1791 		    slots = (SlotsData *)op->co_client;
1792 
1793 		    for (j = 0; j < 8; j++)
1794 		    {
1795 			switch (j) {
1796 			   case 0: bvalue = slots->sl_sborder; break;
1797 			   case 1: bvalue = slots->sl_ssize; break;
1798 			   case 2: bvalue = slots->sl_ssep; break;
1799 			   case 3: bvalue = slots->sl_lborder; break;
1800 			   case 4: bvalue = slots->sl_lsize; break;
1801 			   case 5: bvalue = slots->sl_lsep; break;
1802 			   case 6: bvalue = slots->sl_offset; break;
1803 			   case 7: bvalue = slots->sl_start; break;
1804 			}
1805 			if (bvalue != 0)
1806 			{
1807 			    if ((j == 1) || (j == 2) || (j == 4) || (j == 5))
1808 			    {
1809 				if (bvalue & 0x1)
1810 				    TxError("Internal error: slot size/sep %d"
1811 						" cannot be halved.\n", bvalue);
1812 				bvalue >>= 1;
1813 			    }
1814 			    c = FindGCF(style->cs_scaleFactor, bvalue);
1815 			    if (c < minReduce) minReduce = c;
1816 			}
1817 		    }
1818 		}
1819 		if (op->co_opcode == CIFOP_SQUARES)
1820 		{
1821 		    squares = (SquaresData *)op->co_client;
1822 
1823 		    for (j = 0; j < 3; j++)
1824 		    {
1825 			switch (j) {
1826 			   case 0: bvalue = squares->sq_border; break;
1827 			   case 1: bvalue = squares->sq_size; break;
1828 			   case 2: bvalue = squares->sq_sep; break;
1829 			}
1830 			if (bvalue != 0)
1831 			{
1832 			    if ((j == 1) || (j == 2))
1833 			    {
1834 				if (bvalue & 0x1)
1835 				    TxError("Internal error: contact size/sep %d"
1836 						" cannot be halved.\n", bvalue);
1837 				bvalue >>= 1;
1838 			    }
1839 			    c = FindGCF(style->cs_scaleFactor, bvalue);
1840 			    if (c < minReduce) minReduce = c;
1841 			}
1842 		    }
1843 		}
1844 		else if (op->co_opcode == CIFOP_SQUARES_G)
1845 		{
1846 		    squares = (SquaresData *)op->co_client;
1847 		    for (j = 0; j < TT_MAXTYPES; j++)
1848 		    {
1849 			switch (j) {
1850 			   case 0: bvalue = squares->sq_border; break;
1851 			   case 1: bvalue = squares->sq_size; break;
1852 			   case 2: bvalue = squares->sq_sep; break;
1853 			   case 3: bvalue = squares->sq_gridx; break;
1854 			   case 4: bvalue = squares->sq_gridy; break;
1855 			}
1856 			if (bvalue != 0)
1857 			{
1858 			    c = FindGCF(style->cs_scaleFactor, bvalue);
1859 			    if (c < minReduce) minReduce = c;
1860 			}
1861 		    }
1862 		}
1863 		/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
1864 		/* of the SquaresData pointer from a following operator	  */
1865 		/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field  */
1866 		/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS	  */
1867 		/* uses it for a string.				  */
1868 		else
1869 		{
1870 		    switch (op->co_opcode)
1871 		    {
1872 			case CIFOP_OR:
1873 			case CIFOP_BBOX:
1874 			case CIFOP_MASKHINTS:
1875 			case CIFOP_BOUNDARY:
1876 			case CIFOP_MAXRECT:
1877 			case CIFOP_NET:
1878 			    break;
1879 			case CIFOP_BRIDGELIM:
1880 			case CIFOP_BRIDGE:
1881 			    bridge = (BridgeData *)op->co_client;
1882 			    c = FindGCF(style->cs_scaleFactor,
1883 						bridge->br_width);
1884 			    if (c < minReduce) minReduce = c;
1885 			    break;
1886 			default:
1887 			    bloats = (BloatData *)op->co_client;
1888 			    for (j = 0; j < TT_MAXTYPES; j++)
1889 			    {
1890 				if (bloats->bl_distance[j] != 0)
1891 				{
1892 				    c = FindGCF(style->cs_scaleFactor,
1893 						bloats->bl_distance[j]);
1894 				    if (c < minReduce) minReduce = c;
1895 				}
1896 			    }
1897 		    }
1898 		}
1899 	    }
1900 	    if (minReduce == 1) break;
1901 	}
1902     }
1903     style->cs_reducer = minReduce;
1904 
1905     /* Debug info --- Tim, 1/3/02 */
1906     /* TxPrintf("Output style %s: scaleFactor=%d, reducer=%d, expander=%d.\n",
1907 		style->cs_name, style->cs_scaleFactor,
1908 		style->cs_reducer, style->cs_expander); */
1909 
1910     /* Compute grow and shrink distances for each layer,
1911      * and remember the largest.
1912      */
1913     cifComputeHalo(style);
1914 
1915     /* Go through the layers to see which ones depend on which
1916      * other ones.  The purpose of this is so that we don't
1917      * have to yank unnecessary layers in processing subcell
1918      * interactions.  Also find out which layers involve only
1919      * a single OR operation, and remember the others specially
1920      * (they'll require fancy CIF geometry processing).
1921      */
1922 
1923     for (i = style->cs_nLayers-1; i >= 0; i -= 1)
1924     {
1925 	TileTypeBitMask ourDepend, ourYank;
1926 	bool needThisLayer;
1927 	int j;
1928 
1929 	ourDepend = DBZeroTypeBits;
1930 	ourYank = DBZeroTypeBits;
1931 
1932 	/* This layer must be computed hierarchically if it is needed
1933 	 * by some other layer that is computed hierarchically, or if
1934 	 * it includes operations that require hierarchical processing.
1935 	 */
1936 
1937 	needThisLayer = TTMaskHasType(&style->cs_hierLayers, i);
1938 
1939 	for (op = style->cs_layers[i]->cl_ops; op != NULL;
1940 		    op = op->co_next)
1941 	{
1942 	    BloatData *bloats;
1943 
1944 	    TTMaskSetMask(&ourDepend, &op->co_cifMask);
1945 	    TTMaskSetMask(&ourYank, &op->co_paintMask);
1946 	    switch (op->co_opcode)
1947 	    {
1948 		case CIFOP_BLOAT:
1949 		case CIFOP_BLOATMAX:
1950 		case CIFOP_BLOATMIN:
1951 		    bloats = (BloatData *)op->co_client;
1952 		    for (j = 0; j < TT_MAXTYPES; j++)
1953 			if (bloats->bl_distance[j] != bloats->bl_distance[TT_SPACE])
1954 			    TTMaskSetType(&ourYank, j);
1955 		    needThisLayer = TRUE;
1956 		    break;
1957 
1958 		case CIFOP_BLOATALL:
1959 		    bloats = (BloatData *)op->co_client;
1960 		    for (j = 0; j < TT_MAXTYPES; j++)
1961 		    {
1962 			if (bloats->bl_distance[j] != 0)
1963 			{
1964 			    if (bloats->bl_plane < 0)
1965 				TTMaskSetType(&ourDepend, j);
1966 			    else
1967 				TTMaskSetType(&ourYank, j);
1968 			}
1969 		    }
1970 		    needThisLayer = TRUE;
1971 		    break;
1972 
1973 		case CIFOP_AND:
1974 		case CIFOP_ANDNOT:
1975 		case CIFOP_SHRINK:
1976 		case CIFOP_CLOSE:
1977 		case CIFOP_BRIDGELIM:
1978 		case CIFOP_BRIDGE:
1979 		    needThisLayer = TRUE;
1980 		    break;
1981 	    }
1982 	}
1983 
1984 	if (needThisLayer)
1985 	{
1986 	    TTMaskSetMask(&style->cs_yankLayers, &ourYank);
1987 	    TTMaskSetType(&style->cs_hierLayers, i);
1988 	    TTMaskSetMask(&style->cs_hierLayers, &ourDepend);
1989 	}
1990     }
1991 
1992     /* Added by Tim, 5/16/19					*/
1993     /* Layers that depend on hierarchically generated layers	*/
1994     /* (i.e., templayers) must themselves be hierarchically	*/
1995     /* processed.						*/
1996 
1997     for (i = 0; i < style->cs_nLayers; i++)
1998     {
1999 	TileTypeBitMask ourDepend, mmask;
2000 
2001 	ourDepend = DBZeroTypeBits;
2002 	for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
2003 	    TTMaskSetMask(&ourDepend, &op->co_cifMask);
2004 
2005 	TTMaskAndMask3(&mmask, &ourDepend, &style->cs_hierLayers);
2006 	if (!TTMaskIsZero(&mmask))
2007 	    TTMaskSetType(&style->cs_hierLayers, i);
2008     }
2009 
2010     /* Added by Tim, 6/17/20:  Do not set dependencies of BOUNDARY  */
2011     /* or BBOX because these are unable to be represented in a	    */
2012     /* hierarchy without producing conflicting parent/child mask    */
2013     /* geometry.  Generally, BOUNDARY and BBOX operations are	    */
2014     /* intended to be restricted to the child cell and should not   */
2015     /* interact hierarchically.  Possibly it would be useful to	    */
2016     /* provide some method to preserve the bounding box information */
2017     /* when flattening?						    */
2018 
2019     for (i = 0; i < style->cs_nLayers; i++)
2020     {
2021 	for (op = style->cs_layers[i]->cl_ops; op != NULL; op = op->co_next)
2022 	{
2023 	    if (op->co_opcode == CIFOP_BOUNDARY || op->co_opcode == CIFOP_BBOX)
2024 	    {
2025 		TTMaskClearType(&style->cs_hierLayers, i);
2026 		break;
2027 	    }
2028 	}
2029     }
2030 
2031     /* Added by Tim, 10/18/04					*/
2032 
2033     /* Go through the layer operators looking for those that	*/
2034     /* contain only OR operators followed by a single SQUARES	*/
2035     /* operator.  If found, set the clientdata record of the OR	*/
2036     /* operator to be a copy of that for the SQUARES operator.	*/
2037     /* This is used by the GDS generator when the "gds contact	*/
2038     /* on" option is enabled (CalmaContactArrays is TRUE) to	*/
2039     /* translate contact areas into contact subcell arrays.	*/
2040 
2041     for (i = 0; i < style->cs_nLayers; i++)
2042     {
2043 	ClientData clientdata;
2044 	for (op = style->cs_layers[i]->cl_ops; (op != NULL) &&
2045 			(op->co_opcode == CIFOP_OR) &&
2046 			(TTMaskIsZero(&op->co_cifMask)); op = op->co_next);
2047 	if (op && (op->co_opcode == CIFOP_SQUARES) && (op->co_next == NULL))
2048 	{
2049 	    clientdata = op->co_client;
2050 	    for (op = style->cs_layers[i]->cl_ops; op->co_opcode == CIFOP_OR;
2051 			op = op->co_next)
2052 	    {
2053 		/* Copy the client record from the CIFOP_SQUARES operator
2054 		 * into the CIFOP_OR operator.
2055 		 */
2056 		op->co_client = clientdata;
2057 	    }
2058 	}
2059     }
2060 
2061     /* Uncomment this code to print out information about which
2062      * layers have to be processed hierarchically.
2063 
2064     for (i = 0; i < DBNumUserLayers; i++)
2065     {
2066 	if (TTMaskHasType(&style->cs_yankLayers, i))
2067 	    TxPrintf("Will have to yank %s in style %s.\n",
2068 			DBTypeLongName(i), style->cs_name);
2069     }
2070     for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
2071     {
2072 	if (TTMaskHasType(&style->cs_hierLayers, i))
2073 	    TxPrintf("Layer %s must be processed hierarchically.\n",
2074 			style->cs_layers[i]->cl_name);
2075     }
2076 
2077      */
2078 }
2079 
2080 /*
2081  * ----------------------------------------------------------------------------
2082  *
2083  * CIFLoadStyle --
2084  *
2085  * Re-read the technology file to load the specified technology cif output
2086  * style into structure CIFCurStyle.  This is much more memory-efficient than
2087  * keeping a separate structure for each cif output style.  It incurs a complete
2088  * reading of the tech file on startup and every time the cif output style is
2089  * changed, but we can assume that this does not happen often.  The first
2090  * style in the technology file is assumed to be default, so that re-reading
2091  * the tech file is not necessary on startup unless the default cif output
2092  * style is changed by a call to "cif ostyle".
2093  *
2094  * ----------------------------------------------------------------------------
2095  */
2096 
2097 void
CIFLoadStyle(stylename)2098 CIFLoadStyle(stylename)
2099     char *stylename;
2100 {
2101     SectionID invcif;
2102 
2103     if (CIFCurStyle && (CIFCurStyle->cs_name == stylename)) return;
2104 
2105     cifTechNewStyle();
2106     CIFCurStyle->cs_name = stylename;
2107 
2108     invcif = TechSectionGetMask("cifoutput", NULL);
2109     TechLoad(NULL, invcif);
2110 
2111     /* CIFTechFinal(); */  /* handled by TechLoad() */
2112     CIFTechOutputScale(DBLambda[0], DBLambda[1]);
2113 
2114     /* If the DRC section makes reference to CIF layers, then	*/
2115     /* we need to re-read the DRC section as well.		*/
2116 
2117     if ((DRCForceReload == TRUE) && (DRCCurStyle != NULL))
2118 	DRCReloadCurStyle();
2119 }
2120 
2121 /*
2122  * ----------------------------------------------------------------------------
2123  *
2124  * CIFGetContactSize --
2125  *
2126  *   Return the smallest allowable contact size in lambda units corresponding
2127  *   to the "squares" function operating on the indicated type.  This value
2128  *   is computed as the (cut size) + 2 * (cut border).
2129  *
2130  *   9/12/2013:  Added "squares-grid" and "slots" to the functions understood
2131  *   by the routine.  "squares-grid" behaves the same as "squares".  "slots"
2132  *   can be used for contact cuts with differing metal overlap on different
2133  *   sides.  Normally this would define a square slot;  this routine finds
2134  *   the minimum cut size for the slot.
2135  *
2136  * Results:
2137  *	Contact minimum dimension, in CIF/GDS units
2138  *
2139  * Side effects:
2140  *	If any of edge, border, or spacing is non-NULL, the appropriate
2141  *	cut dimension is filled in.
2142  *
2143  * ----------------------------------------------------------------------------
2144  */
2145 
2146 int
CIFGetContactSize(type,edge,spacing,border)2147 CIFGetContactSize(type, edge, spacing, border)
2148     TileType type;
2149     int *edge;
2150     int *border;
2151     int *spacing;
2152 {
2153     CIFStyle *style = CIFCurStyle;
2154     CIFOp *op, *sop;
2155     int i;
2156     SquaresData *squares;
2157     SlotsData *slots;
2158 
2159     if (style == NULL)
2160     {
2161 	edge = spacing = border = 0;
2162 	return 0;
2163     }
2164 
2165     for (i = 0; i < style->cs_nLayers; i++)
2166     {
2167 	for (op = style->cs_layers[i]->cl_ops; (op != NULL) &&
2168 			(op->co_opcode == CIFOP_OR) &&
2169 			(TTMaskIsZero(&op->co_cifMask)); op = op->co_next)
2170 	    if (TTMaskHasType(&op->co_paintMask, type))
2171 		for (sop = op->co_next; sop != NULL; sop = sop->co_next)
2172 		{
2173 		    if (sop->co_opcode == CIFOP_SQUARES ||
2174 				sop->co_opcode == CIFOP_SQUARES_G)
2175 		    {
2176 			squares = (SquaresData *)sop->co_client;
2177 			if (edge != NULL) *edge = squares->sq_size;
2178 			if (border != NULL) *border = squares->sq_border;
2179 			if (spacing != NULL) *spacing = squares->sq_sep;
2180 			return (squares->sq_size + (squares->sq_border << 1));
2181 		    }
2182 		    else if (sop->co_opcode == CIFOP_SLOTS)
2183 		    {
2184 			slots = (SlotsData *)sop->co_client;
2185 			if (edge != NULL) *edge = slots->sl_ssize;
2186 			if (border != NULL) *border = slots->sl_sborder;
2187 			if (spacing != NULL) *spacing = slots->sl_ssep;
2188 			return (slots->sl_ssize + (slots->sl_sborder << 1));
2189 		    }
2190 
2191 		    /* Anything other than an OR function will break	*/
2192 		    /* the relationship between magic layers and cuts.	*/
2193 		    /* NOTE:  Making an exception for AND_NOT, which is	*/
2194 		    /* used to distinguish between small and large via	*/
2195 		    /* areas.						*/
2196 		    else if ((sop->co_opcode != CIFOP_OR) &&
2197 				(sop->co_opcode != CIFOP_ANDNOT))
2198 			break;
2199 		}
2200     }
2201     return 0;
2202 }
2203 
2204 
2205 /*
2206  * ----------------------------------------------------------------------------
2207  *
2208  * CIFTechOutputScale(n, d) --
2209  *
2210  *   Scale all CIF output scale factors to make them equivalent
2211  *   to reducing the magic internal unit spacing by a factor of n/d.
2212  *   It is important not to reduce the scaleFactor to zero!  So, we
2213  *   multiply scaleFactor by n and the expander by d, then reduce
2214  *   the fraction using the FindGCF routine (utils/fraction.c).
2215  *
2216  *   Because all CIF operation distances (grow, shrink, bloat, squares)
2217  *   are in units of centimicrons multiplied by the expander (e.g.,
2218  *   expander = 10 means units are in nanometers), we need to rescale them
2219  *   by the expander.  To optimize CIF output, the fraction scale/expander
2220  *   is reduced to minimize expander;  that is, to make the numbers in the
2221  *   CIF output as small as possible while making sure all output can be
2222  *   represented by integers.
2223  *
2224  *   Note that because contacts may be placed at 1/2 grid spacing to
2225  *   center them, the size and spacing of contacts as given in the
2226  *   "squares" function must *always* be an even number.  To ensure this,
2227  *   we check for odd numbers in these positions.  If there are any, and
2228  *   "d" is also an odd number, then we multiply both "n" and "d" by 2.
2229  *
2230  *   (Added 2/23/05)---The above is not sufficient!  If the contact size
2231  *   is an odd number, then centering may not be possible even if all
2232  *   the contact parameters are even numbers.  e.g., for size=22 in a 0.18
2233  *   process (scalefactor=9), a 5x5 lambda contact is 45x45 centimicrons.
2234  *   45 - 22 = 23, so border is 11.5 centimicrons.  Therefore, when
2235  *   the scalefactor is even, the contact size must be even, but when the
2236  *   scalefactor is odd, then we have to multiply both "n" and "d" by 2
2237  *   regardless, since contact areas may be either odd or even (compare
2238  *   the above example to one where the contact is drawn 6x6 lambda).
2239  *
2240  * ----------------------------------------------------------------------------
2241  */
2242 
2243 void
CIFTechOutputScale(n,d)2244 CIFTechOutputScale(n, d)
2245     int n, d;
2246 {
2247     int i, j, lgcf, lexpand;
2248     CIFStyle *ostyle = CIFCurStyle;
2249     CIFLayer *cl;
2250     CIFOp *op;
2251     SquaresData *squares;
2252     SlotsData *slots;
2253     BloatData *bloats;
2254     BridgeData *bridge;
2255     bool has_odd_space = FALSE;
2256 
2257     if (ostyle == NULL) return;
2258 
2259     /* For contact half-grid centering, check for odd numbers. . . */
2260 
2261     if (ostyle->cs_scaleFactor & 0x1)
2262     {
2263 	n *= 2;
2264 	d *= 2;
2265 	has_odd_space = TRUE;
2266     }
2267     else if (d & 0x1)
2268     {
2269 	has_odd_space = FALSE;
2270 	for (i = 0; i < ostyle->cs_nLayers; i++)
2271 	{
2272 	    cl = ostyle->cs_layers[i];
2273 	    for (op = cl->cl_ops; op != NULL; op = op->co_next)
2274 	    {
2275 		if (op->co_opcode == CIFOP_SQUARES)
2276 		{
2277 		    squares = (SquaresData *)op->co_client;
2278 		    if ((squares->sq_size & 0x01) || (squares->sq_sep & 0x01))
2279 		    {
2280 			has_odd_space = TRUE;
2281 			break;
2282 		    }
2283 		}
2284 		else if (op->co_opcode == CIFOP_SLOTS)
2285 		{
2286 		    slots = (SlotsData *)op->co_client;
2287 		    if ((slots->sl_lsize & 0x01) || (slots->sl_lsep & 0x01)
2288 			|| (slots->sl_ssize & 0x01) || (slots->sl_ssep & 0x01))
2289 		    {
2290 			has_odd_space = TRUE;
2291 			break;
2292 		    }
2293 		}
2294 	    }
2295 
2296 	    if (has_odd_space)
2297 	    {
2298 		n *= 2;
2299 		d *= 2;
2300 		has_odd_space = FALSE;
2301 		break;
2302 	    }
2303 	}
2304     }
2305 
2306     /* fprintf(stderr, "CIFTechOutputScale(%d, %d)\n", n, d); */
2307 
2308     ostyle->cs_scaleFactor *= n;
2309     ostyle->cs_expander *= d;
2310 
2311     /* fprintf(stderr, "CIFStyle %s:\n", ostyle->cs_name); */
2312 
2313     lexpand = ostyle->cs_expander;
2314     for (i = 0; i < ostyle->cs_nLayers; i++)
2315     {
2316 	cl = ostyle->cs_layers[i];
2317 	for (op = cl->cl_ops; op != NULL; op = op->co_next)
2318 	{
2319 	    if (op->co_distance)
2320 	    {
2321 		op->co_distance *= d;
2322 		lgcf = FindGCF(abs(op->co_distance), ostyle->cs_expander);
2323 		lexpand = FindGCF(lexpand, lgcf);
2324 	    }
2325 	    if (op->co_client)
2326 	    {
2327 		int bvalue, *bptr;
2328 		if (op->co_opcode == CIFOP_SQUARES)
2329 		{
2330 		    squares = (SquaresData *)op->co_client;
2331 		    for (j = 0; j < 3; j++)
2332 		    {
2333 			switch (j) {
2334 			    case 0: bptr = &squares->sq_border; break;
2335 			    case 1: bptr = &squares->sq_size; break;
2336 			    case 2: bptr = &squares->sq_sep; break;
2337 			}
2338 			if (*bptr != 0)
2339 			{
2340 			    (*bptr) *= d;
2341 			    bvalue = abs(*bptr);
2342 			    if ((j == 1) || (j == 2)) bvalue >>= 1;	/* half-grid */
2343 			    if (has_odd_space) bvalue >>= 1;  /* force half-grid */
2344 		            lgcf = FindGCF(bvalue, ostyle->cs_expander);
2345 			    lexpand = FindGCF(lexpand, lgcf);
2346 			}
2347 		    }
2348 		}
2349 		else if (op->co_opcode == CIFOP_SLOTS)
2350 		{
2351 		    slots = (SlotsData *)op->co_client;
2352 		    for (j = 0; j < 8; j++)
2353 		    {
2354 			switch (j) {
2355 			    case 0: bptr = &slots->sl_sborder; break;
2356 			    case 1: bptr = &slots->sl_ssize; break;
2357 			    case 2: bptr = &slots->sl_ssep; break;
2358 			    case 3: bptr = &slots->sl_lborder; break;
2359 			    case 4: bptr = &slots->sl_lsize; break;
2360 			    case 5: bptr = &slots->sl_lsep; break;
2361 			    case 6: bptr = &slots->sl_offset; break;
2362 			    case 7: bptr = &slots->sl_start; break;
2363 			}
2364 			if (*bptr != 0)
2365 			{
2366 			    (*bptr) *= d;
2367 			    bvalue = abs(*bptr);
2368 			    if ((j == 1) || (j == 2) || (j == 4) || (j == 5))
2369 				bvalue >>= 1;	/* half-grid */
2370 			    if (has_odd_space) bvalue >>= 1;  /* force half-grid */
2371 		            lgcf = FindGCF(bvalue, ostyle->cs_expander);
2372 			    lexpand = FindGCF(lexpand, lgcf);
2373 			}
2374 		    }
2375 		}
2376 		else if (op->co_opcode == CIFOP_SQUARES_G)
2377 		{
2378 		    squares = (SquaresData *)op->co_client;
2379 		    for (j = 0; j < 5; j++)
2380 		    {
2381 			switch (j) {
2382 			    case 0: bptr = &squares->sq_border; break;
2383 			    case 1: bptr = &squares->sq_size; break;
2384 			    case 2: bptr = &squares->sq_sep; break;
2385 			    case 3: bptr = &squares->sq_gridx; break;
2386 			    case 4: bptr = &squares->sq_gridy; break;
2387 			}
2388 			if (*bptr != 0)
2389 			{
2390 			    (*bptr) *= d;
2391 		            lgcf = FindGCF(abs(*bptr), ostyle->cs_expander);
2392 			    lexpand = FindGCF(lexpand, lgcf);
2393 			}
2394 		    }
2395 		}
2396 		/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
2397 		/* of the SquaresData pointer from a following operator	  */
2398 		/* CIFOP_BBOX uses the co_client field as a flag field.	  */
2399 		else
2400 		{
2401 		    switch (op->co_opcode)
2402 		    {
2403 			case CIFOP_OR:
2404 			case CIFOP_BBOX:
2405 			case CIFOP_BOUNDARY:
2406 			case CIFOP_MASKHINTS:
2407 			case CIFOP_MAXRECT:
2408 			case CIFOP_NET:
2409 			    break;
2410 			case CIFOP_BRIDGELIM:
2411 			case CIFOP_BRIDGE:
2412 			    bridge = (BridgeData *)op->co_client;
2413 			    bridge->br_width *= d;
2414 		            lgcf = FindGCF(abs(bridge->br_width),
2415 					ostyle->cs_expander);
2416 			    lexpand = FindGCF(lexpand, lgcf);
2417 			    break;
2418 			default:
2419 			    bloats = (BloatData *)op->co_client;
2420 			    for (j = 0; j < TT_MAXTYPES; j++)
2421 			    {
2422 				if (bloats->bl_distance[j] != 0)
2423 				{
2424 				    bloats->bl_distance[j] *= d;
2425 		        	    lgcf = FindGCF(abs(bloats->bl_distance[j]),
2426 						ostyle->cs_expander);
2427 				    lexpand = FindGCF(lexpand, lgcf);
2428 				}
2429 			    }
2430 		    }
2431 		}
2432 	    }
2433 	    /* time-saving quick check */
2434 	    if ((lexpand == 1) && (d == 1)) break;
2435 	}
2436     }
2437 
2438     /* Recompute drc-cif rule distances */
2439     drcCifScale(d, 1);
2440 
2441     /* Reduce the scale and all distances by the greatest common	*/
2442     /* factor of everything.						*/
2443 
2444     /* fprintf(stderr, "All CIF units divisible by %d\n", lexpand); */
2445     /* fflush(stderr); */
2446 
2447     lgcf = FindGCF(ostyle->cs_scaleFactor, ostyle->cs_expander);
2448     if (lgcf < lexpand) lexpand = lgcf;
2449     if (lexpand <= 1) return;
2450 
2451     /* fprintf(stderr, "Expander goes from %d to %d\n", ostyle->cs_expander,
2452      	ostyle->cs_expander / lexpand); */
2453     /* fprintf(stderr, "All CIF op distances are divided by %d\n", lexpand); */
2454     /* fflush(stderr); */
2455 
2456     ostyle->cs_scaleFactor /= lexpand;
2457     ostyle->cs_expander /= lexpand;
2458 
2459     for (i = 0; i < ostyle->cs_nLayers; i++)
2460     {
2461 	cl = ostyle->cs_layers[i];
2462 	for (op = cl->cl_ops; op != NULL; op = op->co_next)
2463 	{
2464 	    if (op->co_distance)
2465 		op->co_distance /= lexpand;
2466 
2467 	    if (op->co_client)
2468 	    {
2469 		int nlayers;
2470 		switch (op->co_opcode)
2471 		{
2472 		    case CIFOP_SLOTS:
2473 			slots = (SlotsData *)op->co_client;
2474 			if (slots->sl_sborder != 0)
2475 			    slots->sl_sborder /= lexpand;
2476 			if (slots->sl_ssize != 0)
2477 			    slots->sl_ssize /= lexpand;
2478 			if (slots->sl_ssep != 0)
2479 			    slots->sl_ssep /= lexpand;
2480 			if (slots->sl_lborder != 0)
2481 			    slots->sl_lborder /= lexpand;
2482 			if (slots->sl_lsize != 0)
2483 			    slots->sl_lsize /= lexpand;
2484 			if (slots->sl_lsep != 0)
2485 			    slots->sl_lsep /= lexpand;
2486 			if (slots->sl_offset != 0)
2487 			    slots->sl_offset /= lexpand;
2488 			if (slots->sl_start != 0)
2489 			    slots->sl_start /= lexpand;
2490 			break;
2491 		    case CIFOP_SQUARES_G:
2492 			squares = (SquaresData *)op->co_client;
2493 			if (squares->sq_gridx != 0)
2494 			    squares->sq_gridx /= lexpand;
2495 			if (squares->sq_gridy != 0)
2496 			    squares->sq_gridy /= lexpand;
2497 			/* (drop through) */
2498 		    case CIFOP_SQUARES:
2499 			squares = (SquaresData *)op->co_client;
2500 			if (squares->sq_border != 0)
2501 			    squares->sq_border /= lexpand;
2502 			if (squares->sq_size != 0)
2503 			    squares->sq_size /= lexpand;
2504 			if (squares->sq_sep != 0)
2505 			    squares->sq_sep /= lexpand;
2506 			break;
2507 		    case CIFOP_BLOAT:
2508 		    case CIFOP_BLOATMIN:
2509 		    case CIFOP_BLOATMAX:
2510 			bloats = (BloatData *)op->co_client;
2511 			for (j = 0; j < TT_MAXTYPES; j++)
2512 			    if (bloats->bl_distance[j] != 0)
2513 				bloats->bl_distance[j] /= lexpand;
2514 			break;
2515 		    case CIFOP_BRIDGELIM:
2516 		    case CIFOP_BRIDGE:
2517 			bridge = (BridgeData *)op->co_client;
2518 			bridge->br_width /= lexpand;
2519 			break;
2520 		    default:
2521 			/* op->co_opcode in CIFOP_OR is a pointer copy,	*/
2522 			/* in CIFOP_BBOX and CIFOP_MAXRECT is a	flag,	*/
2523 			/* and in CIFOP_NET and CIFOP_MASKHINTS is a	*/
2524 			/* string.					*/
2525 			break;
2526 		}
2527 	    }
2528 	}
2529     }
2530 
2531     /* Recompute drc-cif rule distances */
2532     drcCifScale(1, lexpand);
2533 
2534     /* Recompute value of cs_radius */
2535     cifComputeHalo(ostyle);
2536 }
2537