Extended the method of the previous commit to include the command

option "drc find <text>", to find the next error of a specific
type based on the contents of the DRC error message (e.g.,
"drc find li.1").
This commit is contained in:
Tim Edwards 2023-06-26 21:17:51 -04:00
parent 60a378842f
commit 3ae24e8a8c
3 changed files with 73 additions and 18 deletions

View File

@ -3935,8 +3935,10 @@ CmdDrc(w, cmd)
bool incremental;
bool doforall = FALSE;
bool dolist = FALSE;
bool findonly;
int drc_start;
int count_total;
LinkedIndex *DRCSaveRules = NULL;
DRCCountList *dcl;
int argc = cmd->tx_argc;
char **argv = cmd->tx_argv;
@ -4165,7 +4167,8 @@ CmdDrc(w, cmd)
rootDef = rootUse->cu_def;
incremental = FALSE;
if (argc == 3 && StrIsInt(argv[2]))
findonly = FALSE;
if ((argc == 3) && StrIsInt(argv[2]))
{
drc_nth = atoi(argv[2]);
if (drc_nth <= 0) drc_nth = 1;
@ -4174,6 +4177,30 @@ CmdDrc(w, cmd)
{
incremental = TRUE;
drc_nth++;
/* If 3rd argument is a string, then look only for
* rules containing the string text.
*/
if (argc == 3)
{
int i;
findonly = TRUE;
DRCSaveRules = DRCIgnoreRules;
DRCIgnoreRules = NULL;
for (i = 1; i < DRCCurStyle->DRCWhySize; i++)
{
if (strstr(DRCCurStyle->DRCWhyList[i], argv[2]) != NULL)
{
LinkedIndex *newli;
newli = (LinkedIndex *)mallocMagic(sizeof(LinkedIndex));
newli->li_index = i;
newli->li_next = DRCIgnoreRules;
DRCIgnoreRules = newli;
}
}
}
}
drc_start = -1;
@ -4207,7 +4234,7 @@ CmdDrc(w, cmd)
if (!dolist)
#endif
TxPrintf("Error area #%d:\n", result);
if (DRCWhy(dolist, rootUse, &area)) break;
if (DRCWhy(dolist, rootUse, &area, findonly)) break;
drc_nth++;
}
else if (result < 0)
@ -4232,6 +4259,17 @@ CmdDrc(w, cmd)
if (drc_start < 0)
drc_start = result;
}
if (findonly)
{
/* Delete temporary rules */
while (DRCIgnoreRules != NULL)
{
freeMagic(DRCIgnoreRules);
DRCIgnoreRules = DRCIgnoreRules->li_next;
}
/* Replace temporary set of rules */
DRCIgnoreRules = DRCSaveRules;
}
break;
case DRC_HALO:
@ -4309,14 +4347,11 @@ CmdDrc(w, cmd)
if (argc != 3) goto badusage;
if (!strcasecmp(argv[2], "none"))
{
LinkedIndex *li;
li = DRCIgnoreRules;
while (li != NULL)
while (DRCIgnoreRules != NULL)
{
freeMagic(li);
li = li->li_next;
freeMagic(DRCIgnoreRules);
DRCIgnoreRules = DRCIgnoreRules->li_next;
}
DRCIgnoreRules = (LinkedIndex *)NULL;
}
else
{
@ -4422,7 +4457,7 @@ CmdDrc(w, cmd)
DRCWhyAll(rootUse, &rootArea, NULL);
else
#endif
if (!DRCWhy(dolist, rootUse, &rootArea))
if (!DRCWhy(dolist, rootUse, &rootArea, FALSE))
TxPrintf("No errors found.\n");
break;
}

View File

@ -37,8 +37,10 @@ Background design rule checker control and status.
<DD> Count and report error tiles in the edit cell.
<DT> <B>euclidean on</B>|<B>off</B>
<DD> Enable/disable Euclidean geometry checking
<DT> <B>find</B> [<I>nth</I>]
<DD> Locate next (or <I>nth</I>) error in current cell
<DT> <B>find</B> [<I>nth</I>|<I>text</I>]
<DD> Locate next (or <I>nth</I>) error in current cell; if string
<I>text</I> is given instead of an integer, then search for the
next error of a type containing the text.
<DT> <B>help</B>
<DD> Print help information
<DT> <B>ignore</B> [<I>text</I>|<B>none</B>]

View File

@ -470,7 +470,7 @@ DRCPrintStats()
*/
bool
DRCWhy(dolist, use, area)
DRCWhy(dolist, use, area, findonly)
bool dolist; /*
* Generate Tcl list for value
*/
@ -480,6 +480,11 @@ DRCWhy(dolist, use, area)
Rect *area; /* Area, in def's coordinates, that
* is to be checked.
*/
bool findonly; /* If TRUE, contents of DRCIgnoreRules
* are inverted; that is, flag only
* the marked rules instead of ignoring
* them.
*/
{
SearchContext scx;
Rect box;
@ -490,13 +495,26 @@ DRCWhy(dolist, use, area)
/* Create a hash table to eliminate duplicate messages. */
DRCErrorList = (int *)mallocMagic((DRCCurStyle->DRCWhySize + 1) * sizeof(int));
for (i = 0; i <= DRCCurStyle->DRCWhySize; i++)
DRCErrorList[i] = 0;
/* Ignore rules as specified by setting the DRCErrorList entry to */
/* -1, indicating that the error type should be ignored. */
for (li = DRCIgnoreRules; li; li = li->li_next)
DRCErrorList[li->li_index] = -1;
if (!findonly)
{
for (i = 0; i <= DRCCurStyle->DRCWhySize; i++)
DRCErrorList[i] = 0;
/* Ignore rules as specified by setting the DRCErrorList entry to */
/* -1, indicating that the error type should be ignored. */
for (li = DRCIgnoreRules; li; li = li->li_next)
DRCErrorList[li->li_index] = -1;
}
else
{
/* Inverted behavior: Only look at rules in the DRCIgnoreRules list */
for (i = 0; i <= DRCCurStyle->DRCWhySize; i++)
DRCErrorList[i] = -1;
for (li = DRCIgnoreRules; li; li = li->li_next)
DRCErrorList[li->li_index] = 0;
}
DRCErrorCount = 0;
box = DRCdef->cd_bbox;