magic/cif/CIFmain.c

414 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* CIFmain.c -
*
* This file contains global information for the CIF module,
* such as performance statistics.
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFmain.c,v 1.3 2009/01/15 15:44:34 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <string.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "cif/CIFint.h"
#include "textio/textio.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/styles.h"
/* The following points to a list of all the CIF output styles
* currently understood:
*/
CIFKeep *CIFStyleList;
/* The current style being used for CIF output: */
CIFStyle *CIFCurStyle = NULL;
/* The following are statistics gathered at various points in
* CIF processing. There are two versions of each statistic:
* a total number, and the number since stats were last printed.
*/
int CIFTileOps = 0; /* Total tiles touched in geometrical
* operations.
*/
int CIFHierTileOps = 0; /* Tiles touched in geometrical operations
* as part of hierarchical processing.
*/
int CIFRects = 0; /* Total CIF rectangles output. */
int CIFHierRects = 0; /* Rectangles stemming from interactions. */
static int cifTotalTileOps = 0;
static int cifTotalHierTileOps = 0;
static int cifTotalRects = 0;
static int cifTotalHierRects = 0;
/* This file provides several procedures for dealing with errors during
* the CIF generation process. Low-level CIF artwork-manipulation
* procedures call CIFError without knowing what cell CIF is being
* generated for, or what layer is being generated. Higher-level
* routines are responsible for recording that information in the
* variables below so that CIFError can output meaningful diagnostics
* using the feedback mechanism.
*/
global CellDef *CIFErrorDef; /* Definition in which to record errors. */
global int CIFErrorLayer; /* Index of CIF layer associated with errors.*/
/*
* ----------------------------------------------------------------------------
*
* CIFPrintStats --
*
* This procedure prints out CIF statistics including both
* total values and counts since the last printing.
*
* Results:
* None.
*
* Side effects:
* Several messages are printed.
*
* ----------------------------------------------------------------------------
*/
void
CIFPrintStats()
{
TxPrintf("CIF statistics (recent/total):\n");
cifTotalTileOps += CIFTileOps;
TxPrintf(" Geometrical tile operations: %d/%d\n",
CIFTileOps, cifTotalTileOps);
CIFTileOps = 0;
cifTotalHierTileOps += CIFHierTileOps;
TxPrintf(" Tile operations for hierarchy: %d/%d\n",
CIFHierTileOps, cifTotalHierTileOps);
CIFHierTileOps = 0;
cifTotalRects += CIFRects;
TxPrintf(" CIF rectangles output: %d/%d\n",
CIFRects, cifTotalRects);
CIFRects = 0;
cifTotalHierRects += CIFHierRects;
TxPrintf(" CIF rectangles due to hierarchical interactions: %d/%d\n",
CIFHierRects, cifTotalHierRects);
CIFHierRects = 0;
}
/*
* ----------------------------------------------------------------------------
*
* CIFGetOutputScale --
*
* This routine is given here so that the CIF output scale can be
* accessed from the "commands" directory source without declaring
* external references to CIF global variables.
*
* Results:
* Internal units-to-(nanometers * convert) conversion factor (float).
* Use convert = 1000 for centimicrons-to-microns conversion
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
float
CIFGetOutputScale(convert)
int convert;
{
if (CIFCurStyle == NULL) return 1.0;
return ((float)(10 * CIFCurStyle->cs_scaleFactor) /
(float)(CIFCurStyle->cs_expander * convert));
}
/*
* ----------------------------------------------------------------------------
*
* CIFPrintStyle --
*
* This procedure prints the current CIF output style or list
* of known styles.
*
* Results:
* None.
*
* Side effects:
* Output.
*
* ----------------------------------------------------------------------------
*/
void
CIFPrintStyle(dolist, doforall, docurrent)
bool dolist; /* Return as a list if true */
bool doforall; /* Print all known styles if true */
bool docurrent; /* Print current style if true */
{
CIFKeep *style;
if (docurrent)
{
if (CIFCurStyle == NULL)
TxError("Error: No style is set\n");
else
{
if (!dolist) TxPrintf("The current style is \"");
#ifdef MAGIC_WRAPPER
if (dolist)
Tcl_SetResult(magicinterp, CIFCurStyle->cs_name, NULL);
else
#endif
TxPrintf("%s", CIFCurStyle->cs_name);
if (!dolist) TxPrintf("\".\n");
}
}
if (doforall)
{
if (!dolist) TxPrintf("The CIF output styles are: ");
for (style = CIFStyleList; style != NULL; style = style->cs_next)
{
if (dolist)
{
#ifdef MAGIC_WRAPPER
Tcl_AppendElement(magicinterp, style->cs_name);
#else
if (style != CIFStyleList) TxPrintf(" ");
TxPrintf("%s", style->cs_name);
#endif
}
else
{
if (style != CIFStyleList) TxPrintf(", ");
TxPrintf("%s", style->cs_name);
}
}
if (!dolist) TxPrintf(".\n");
}
}
/*
* ----------------------------------------------------------------------------
*
* CIFSetStyle --
*
* This procedure changes the current CIF output style to the one
* named by the parameter.
*
* Results:
* None.
*
* Side effects:
* The current CIF style is changed. If the name doesn't match,
* or is ambiguous, then a list of all CIF styles is output.
*
* ----------------------------------------------------------------------------
*/
void
CIFSetStyle(name)
char *name; /* Name of the new style. If NULL, just
* print out the valid styles.
*/
{
CIFKeep *style, *match;
int length;
if (name == NULL) return;
match = NULL;
length = strlen(name);
for (style = CIFStyleList; style != NULL; style = style->cs_next)
{
if (strncmp(name, style->cs_name, length) == 0)
{
if (match != NULL)
{
TxError("CIF output style \"%s\" is ambiguous.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
return;
}
match = style;
}
}
if (match != NULL)
{
CIFLoadStyle(match->cs_name);
TxPrintf("CIF output style is now \"%s\"\n", name);
return;
}
TxError("\"%s\" is not one of the CIF output styles Magic knows.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
}
/*
* ----------------------------------------------------------------------------
*
* CIFNameToMask --
*
* Finds the CIF planes for a given name.
*
* Results:
* Returns TRUE on success, or FALSE if "name" failed to match any layers.
*
* Side effects:
* If there's no match, then an error message is output.
* The sets 'result' to be all types containing the CIF layer named
* "name". The current CIF style is used for the lookup. If "depend"
* is non-NULL, then it is filled with the mask of all layers on which
* the named layer depends.
* ----------------------------------------------------------------------------
*/
bool
CIFNameToMask(name, result, depend)
char *name;
TileTypeBitMask *result;
TileTypeBitMask *depend;
{
int i, j;
CIFOp *op;
CIFLayer *cl;
if (!CIFCurStyle)
{
TxError("No CIF output style set!\n");
return FALSE;
}
TTMaskZero(result);
for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
if (strcmp(name, CIFCurStyle->cs_layers[i]->cl_name) == 0)
TTMaskSetType(result, i);
if (!TTMaskEqual(result, &DBZeroTypeBits))
{
/* This loop depends on the fact that templayers must */
/* be declared in order of dependency; that is, you */
/* can't use a layer before it is declared. Thus, the */
/* dependent layers will always be filled in from layer */
/* i back to zero. */
if (depend)
{
TTMaskZero(depend);
TTMaskSetMask(depend, result);
for (j = CIFCurStyle->cs_nLayers - 1; j >= 0; j--)
if (TTMaskHasType(depend, j))
{
cl = CIFCurStyle->cs_layers[j];
for (op = cl->cl_ops; op != NULL; op = op->co_next)
TTMaskSetMask(depend, &op->co_cifMask);
}
}
return TRUE;
}
TxError("CIF name \"%s\" doesn't exist in style \"%s\".\n", name,
CIFCurStyle->cs_name);
TxError("The valid CIF layer names are: ");
for (i = 0; i < CIFCurStyle->cs_nLayers; i++)
{
if (i == 0)
TxError("%s", CIFCurStyle->cs_layers[i]->cl_name);
else
TxError(", %s", CIFCurStyle->cs_layers[i]->cl_name);
}
TxError(".\n");
return FALSE;
}
/*
* ----------------------------------------------------------------------------
*
* CIFError --
*
* This procedure is called by low-level CIF generation routines
* when a problem is encountered in generating CIF. This procedure
* notes the problem using the feedback mechanism.
*
* Results:
* None.
*
* Side effects:
* Feedback information is added. The caller must have set CIFErrorDef
* to point to the cell definition that area refers to. If CIFErrorDef
* is NULL, then errors are ignored.
*
* ----------------------------------------------------------------------------
*/
void
CIFError(area, message)
Rect *area; /* Place in CIFErrorDef where there was a
* problem in generating CIFErrorLayer.
*/
char *message; /* Short note about what went wrong. */
{
char msg[200];
if (CIFCurStyle->cs_flags & CWF_NO_ERRORS) return;
if (CIFErrorDef == (NULL)) return;
(void) sprintf(msg, "CIF error in cell %s, layer %s: %s",
CIFErrorDef->cd_name, CIFCurStyle->cs_layers[CIFErrorLayer]->cl_name,
message);
DBWFeedbackAdd(area, msg, CIFErrorDef, CIFCurStyle->cs_scaleFactor,
STYLE_PALEHIGHLIGHTS);
}
/*
* ----------------------------------------------------------------------------
*
* CIFOutputScaleFactor --
*
* Returns current conversion factor between CIF units and
* Magic units.
*
* Results:
* The return value is the number of centimicrons per Magic
* unit in the current CIF output style. If there is no
* known CIF output style, 1 is returned.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
int
CIFOutputScaleFactor()
{
if (CIFCurStyle == NULL) return 1;
return CIFCurStyle->cs_scaleFactor;
}