Yet another pass at the problem caused by implementing DRC
exceptions; avoided the use of "signed char" altogether by just making the drcc_exception value a bit mask with the lower 7 bits being the index and the upper bit being the flag for exception (0) vs. exemption (1), with the value 0xff being reserved for "none" (no exception or exemption). This implementation should avoid any issues caused by ambiguity in the use of signed vs. unsigned char.
This commit is contained in:
parent
460a357730
commit
e789f18523
|
|
@ -765,13 +765,12 @@ drcTile (tile, dinfo, arg)
|
|||
cptr = cptr->drcc_next)
|
||||
{
|
||||
/* Handle rule exceptions and exemptions */
|
||||
if (cptr->drcc_exception != (char)DRC_EXCEPTION_NONE)
|
||||
if (cptr->drcc_exception != DRC_EXCEPTION_NONE)
|
||||
{
|
||||
PropertyRecord *proprec;
|
||||
bool propfound, isinside = FALSE;
|
||||
char *name;
|
||||
signed char idx = cptr->drcc_exception;
|
||||
if (idx < 0) idx = -idx - 1;
|
||||
int idx = cptr->drcc_exception & ~DRC_EXCEPTION_MASK;
|
||||
name = DRCCurStyle->DRCExceptionList[idx];
|
||||
|
||||
/* Is there any exception area defined? */
|
||||
|
|
@ -797,8 +796,10 @@ drcTile (tile, dinfo, arg)
|
|||
* an exception area. Exception rules are ignored if
|
||||
* the edge is outside an exception area.
|
||||
*/
|
||||
if (!isinside && (cptr->drcc_exception >= 0)) continue;
|
||||
if (isinside && (cptr->drcc_exception < 0)) continue;
|
||||
if (!isinside && ((cptr->drcc_exception & DRC_EXCEPTION_MASK) == 0)))
|
||||
continue;
|
||||
if (isinside && ((cptr->drcc_exception & DRC_EXCEPTION_MASK) == 1)))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* DRC_ANGLES_90 and DRC_SPLITTILE rules are handled by */
|
||||
|
|
@ -1211,24 +1212,17 @@ drcTile (tile, dinfo, arg)
|
|||
cptr = cptr->drcc_next)
|
||||
{
|
||||
/* Handle rule exceptions and exemptions */
|
||||
if (cptr->drcc_exception != (char)DRC_EXCEPTION_NONE)
|
||||
if (cptr->drcc_exception != DRC_EXCEPTION_NONE)
|
||||
{
|
||||
PropertyRecord *proprec;
|
||||
bool propfound, isinside = FALSE;
|
||||
char *name;
|
||||
signed char idx = cptr->drcc_exception;
|
||||
if (idx < 0) idx = -idx - 1;
|
||||
int idx = cptr->drcc_exception & ~DRC_EXCEPTION_MASK;
|
||||
name = DRCCurStyle->DRCExceptionList[idx];
|
||||
|
||||
/* Is there any exception area defined? */
|
||||
proprec = DBPropGet(arg->dCD_celldef, name, &propfound);
|
||||
|
||||
/* Quickest case: Rule is an exception but there are no
|
||||
* exception areas.
|
||||
*/
|
||||
if ((!propfound) && (cptr->drcc_exception >= 0))
|
||||
continue;
|
||||
|
||||
/* If an exception area exists, is the error edge inside? */
|
||||
if (propfound)
|
||||
{
|
||||
|
|
@ -1249,8 +1243,10 @@ drcTile (tile, dinfo, arg)
|
|||
* an exception area. Exception rules are ignored if
|
||||
* the edge is outside an exception area.
|
||||
*/
|
||||
if (isinside && (cptr->drcc_exception < 0)) continue;
|
||||
if (!isinside && (cptr->drcc_exception >= 0)) continue;
|
||||
if (!isinside && ((cptr->drcc_exception & DRC_EXCEPTION_MASK) == 0)))
|
||||
continue;
|
||||
if (isinside && ((cptr->drcc_exception & DRC_EXCEPTION_MASK) == 1)))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* DRC_ANGLES_90 and DRC_SPLITTILE rules are handled by */
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ static int DRCtag = 0;
|
|||
* while reading the DRC tech file section.
|
||||
*/
|
||||
|
||||
static signed char drcCurException = (char)DRC_EXCEPTION_NONE;
|
||||
static unsigned char drcCurException = DRC_EXCEPTION_NONE;
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
|
|
@ -405,7 +405,9 @@ drcWhyCreate(whystring)
|
|||
* not already exist.
|
||||
*
|
||||
* Results:
|
||||
* The index of the exception (which is a signed character).
|
||||
* The index of the exception (which is an unsigned character containing
|
||||
* the index in the lower 7 bits and a high bit indicating if the rule
|
||||
* is an exception (0) or an exemption (1)).
|
||||
*
|
||||
* Side effects:
|
||||
* Adds to the DRCExceptionList if "name" has not been used before.
|
||||
|
|
@ -414,7 +416,7 @@ drcWhyCreate(whystring)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char
|
||||
unsigned char
|
||||
drcExceptionCreate(name)
|
||||
char *name;
|
||||
{
|
||||
|
|
@ -424,13 +426,14 @@ drcExceptionCreate(name)
|
|||
/* NOTE: DRCExceptionList has "MASKHINTS_" prepended to the names */
|
||||
for (i = 0; i < DRCCurStyle->DRCExceptionSize; i++)
|
||||
if (!strcmp(name, DRCCurStyle->DRCExceptionList[i] + 10))
|
||||
return (char)i;
|
||||
return (unsigned char)i;
|
||||
|
||||
if (i > 127)
|
||||
/* Note that i cannot be 127 as this is reserved for DRC_EXCEPTION_NONE */
|
||||
if (i > 126)
|
||||
{
|
||||
/* I would be shocked if this code ever got executed. */
|
||||
TxError("Error: Too many rule exceptions! Limit is 127.\n");
|
||||
return (char)DRC_EXCEPTION_NONE;
|
||||
TxError("Error: Too many rule exceptions! Limit is 126.\n");
|
||||
return DRC_EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/* Create a new list that is one entry longer than the old list.
|
||||
|
|
@ -448,7 +451,7 @@ drcExceptionCreate(name)
|
|||
if (DRCCurStyle->DRCExceptionList != (char **)NULL)
|
||||
freeMagic(DRCCurStyle->DRCExceptionList);
|
||||
DRCCurStyle->DRCExceptionList = newlist;
|
||||
return (char)i;
|
||||
return (unsigned char)i;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -732,7 +735,7 @@ DRCTechStyleInit()
|
|||
}
|
||||
|
||||
drcCifInit();
|
||||
drcCurException = (char)DRC_EXCEPTION_NONE;
|
||||
drcCurException = DRC_EXCEPTION_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3726,9 +3729,10 @@ drcRectangle(argc, argv)
|
|||
* Returns 0.
|
||||
*
|
||||
* Side effects:
|
||||
* Updates drcCurException. drcCurException is zero or positive for
|
||||
* exceptions and negative for exemptions. The index can be
|
||||
* recovered from a negative value by negating it and subtracting 1.
|
||||
* Updates drcCurException. drcCurException contains the index in
|
||||
* the lower 7 bits, and a flag in the upper bit (0 = exception rule,
|
||||
* 1 = exemption rule). The index can be recovered by masking off
|
||||
* the upper bit.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -3745,7 +3749,7 @@ drcException(argc, argv)
|
|||
/* Assume that argc must be 2 because the parser insists upon it */
|
||||
|
||||
if (!strcmp(argv[1], "none"))
|
||||
drcCurException = (char)DRC_EXCEPTION_NONE;
|
||||
drcCurException = DRC_EXCEPTION_NONE;
|
||||
else
|
||||
drcCurException = drcExceptionCreate(argv[1]);
|
||||
return (0);
|
||||
|
|
@ -3763,9 +3767,9 @@ drcExemption(argc, argv)
|
|||
/* Assume that argc must be 2 because the parser insists upon it */
|
||||
|
||||
if (!strcmp(argv[1], "none"))
|
||||
drcCurException = (char)DRC_EXCEPTION_NONE;
|
||||
drcCurException = DRC_EXCEPTION_NONE;
|
||||
else
|
||||
drcCurException = -(drcExceptionCreate(argv[1])) - 1;
|
||||
drcCurException = drcExceptionCreate(argv[1]) | DRC_EXCEPTION_MASK;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ typedef struct drccookie
|
|||
TileTypeBitMask drcc_mask; /* Legal types on RHS */
|
||||
TileTypeBitMask drcc_corner; /* Types that trigger corner check */
|
||||
unsigned short drcc_flags; /* Miscellaneous flags, see below. */
|
||||
signed char drcc_exception; /* Index to list of exceptions */
|
||||
unsigned char drcc_exception; /* Index to list of exceptions */
|
||||
int drcc_edgeplane; /* Plane of edge */
|
||||
int drcc_plane; /* Index of plane on which to check
|
||||
* legal types. */
|
||||
|
|
@ -92,8 +92,10 @@ typedef struct drccookie
|
|||
#define DRC_UNPROCESSED CLIENTDEFAULT
|
||||
#define DRC_PROCESSED 1
|
||||
|
||||
/* drcc_exception defaults to -128 (0x80) meaning no exceptions/exemptions */
|
||||
#define DRC_EXCEPTION_NONE (char)0x80
|
||||
/* drcc_exception defaults to 255 meaning no exceptions/exemptions */
|
||||
#define DRC_EXCEPTION_NONE ((unsigned char)0xff)
|
||||
/* The high bit of the value determines if this is an exception or an exemption.
|
||||
#define DRC_EXCEPTION_MASK ((unsigned char)0x80)
|
||||
|
||||
/*
|
||||
* Background DRC (DRC Idle proc) for Tcl-based Magic
|
||||
|
|
|
|||
Loading…
Reference in New Issue