From e789f18523a1faa63060cf992d04a7b982653b19 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Tue, 24 Mar 2026 09:37:50 -0400 Subject: [PATCH] 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. --- VERSION | 2 +- drc/DRCbasic.c | 28 ++++++++++++---------------- drc/DRCtech.c | 34 +++++++++++++++++++--------------- drc/drc.h | 8 +++++--- 4 files changed, 37 insertions(+), 35 deletions(-) diff --git a/VERSION b/VERSION index 119b32c6..6951ac29 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.626 +8.3.627 diff --git a/drc/DRCbasic.c b/drc/DRCbasic.c index b2692fe6..ef5b7df9 100644 --- a/drc/DRCbasic.c +++ b/drc/DRCbasic.c @@ -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 */ diff --git a/drc/DRCtech.c b/drc/DRCtech.c index c15e9f96..e2193ad8 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -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); } diff --git a/drc/drc.h b/drc/drc.h index 82ed32af..fbd1b96b 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -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