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 incremental;
bool doforall = FALSE; bool doforall = FALSE;
bool dolist = FALSE; bool dolist = FALSE;
bool findonly;
int drc_start; int drc_start;
int count_total; int count_total;
LinkedIndex *DRCSaveRules = NULL;
DRCCountList *dcl; DRCCountList *dcl;
int argc = cmd->tx_argc; int argc = cmd->tx_argc;
char **argv = cmd->tx_argv; char **argv = cmd->tx_argv;
@ -4165,7 +4167,8 @@ CmdDrc(w, cmd)
rootDef = rootUse->cu_def; rootDef = rootUse->cu_def;
incremental = FALSE; incremental = FALSE;
if (argc == 3 && StrIsInt(argv[2])) findonly = FALSE;
if ((argc == 3) && StrIsInt(argv[2]))
{ {
drc_nth = atoi(argv[2]); drc_nth = atoi(argv[2]);
if (drc_nth <= 0) drc_nth = 1; if (drc_nth <= 0) drc_nth = 1;
@ -4174,6 +4177,30 @@ CmdDrc(w, cmd)
{ {
incremental = TRUE; incremental = TRUE;
drc_nth++; 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; drc_start = -1;
@ -4207,7 +4234,7 @@ CmdDrc(w, cmd)
if (!dolist) if (!dolist)
#endif #endif
TxPrintf("Error area #%d:\n", result); TxPrintf("Error area #%d:\n", result);
if (DRCWhy(dolist, rootUse, &area)) break; if (DRCWhy(dolist, rootUse, &area, findonly)) break;
drc_nth++; drc_nth++;
} }
else if (result < 0) else if (result < 0)
@ -4232,6 +4259,17 @@ CmdDrc(w, cmd)
if (drc_start < 0) if (drc_start < 0)
drc_start = result; 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; break;
case DRC_HALO: case DRC_HALO:
@ -4309,14 +4347,11 @@ CmdDrc(w, cmd)
if (argc != 3) goto badusage; if (argc != 3) goto badusage;
if (!strcasecmp(argv[2], "none")) if (!strcasecmp(argv[2], "none"))
{ {
LinkedIndex *li; while (DRCIgnoreRules != NULL)
li = DRCIgnoreRules;
while (li != NULL)
{ {
freeMagic(li); freeMagic(DRCIgnoreRules);
li = li->li_next; DRCIgnoreRules = DRCIgnoreRules->li_next;
} }
DRCIgnoreRules = (LinkedIndex *)NULL;
} }
else else
{ {
@ -4422,7 +4457,7 @@ CmdDrc(w, cmd)
DRCWhyAll(rootUse, &rootArea, NULL); DRCWhyAll(rootUse, &rootArea, NULL);
else else
#endif #endif
if (!DRCWhy(dolist, rootUse, &rootArea)) if (!DRCWhy(dolist, rootUse, &rootArea, FALSE))
TxPrintf("No errors found.\n"); TxPrintf("No errors found.\n");
break; break;
} }

View File

@ -37,8 +37,10 @@ Background design rule checker control and status.
<DD> Count and report error tiles in the edit cell. <DD> Count and report error tiles in the edit cell.
<DT> <B>euclidean on</B>|<B>off</B> <DT> <B>euclidean on</B>|<B>off</B>
<DD> Enable/disable Euclidean geometry checking <DD> Enable/disable Euclidean geometry checking
<DT> <B>find</B> [<I>nth</I>] <DT> <B>find</B> [<I>nth</I>|<I>text</I>]
<DD> Locate next (or <I>nth</I>) error in current cell <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> <DT> <B>help</B>
<DD> Print help information <DD> Print help information
<DT> <B>ignore</B> [<I>text</I>|<B>none</B>] <DT> <B>ignore</B> [<I>text</I>|<B>none</B>]

View File

@ -470,7 +470,7 @@ DRCPrintStats()
*/ */
bool bool
DRCWhy(dolist, use, area) DRCWhy(dolist, use, area, findonly)
bool dolist; /* bool dolist; /*
* Generate Tcl list for value * Generate Tcl list for value
*/ */
@ -480,6 +480,11 @@ DRCWhy(dolist, use, area)
Rect *area; /* Area, in def's coordinates, that Rect *area; /* Area, in def's coordinates, that
* is to be checked. * 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; SearchContext scx;
Rect box; Rect box;
@ -490,13 +495,26 @@ DRCWhy(dolist, use, area)
/* Create a hash table to eliminate duplicate messages. */ /* Create a hash table to eliminate duplicate messages. */
DRCErrorList = (int *)mallocMagic((DRCCurStyle->DRCWhySize + 1) * sizeof(int)); 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 */ if (!findonly)
/* -1, indicating that the error type should be ignored. */ {
for (li = DRCIgnoreRules; li; li = li->li_next) for (i = 0; i <= DRCCurStyle->DRCWhySize; i++)
DRCErrorList[li->li_index] = -1; 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; DRCErrorCount = 0;
box = DRCdef->cd_bbox; box = DRCdef->cd_bbox;