diff --git a/commands/CmdCD.c b/commands/CmdCD.c index 68ffa913..85f4aa69 100644 --- a/commands/CmdCD.c +++ b/commands/CmdCD.c @@ -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; } diff --git a/doc/html/drc.html b/doc/html/drc.html index a2207ee7..e50cad1b 100644 --- a/doc/html/drc.html +++ b/doc/html/drc.html @@ -37,8 +37,10 @@ Background design rule checker control and status.
Count and report error tiles in the edit cell.
euclidean on|off
Enable/disable Euclidean geometry checking -
find [nth] -
Locate next (or nth) error in current cell +
find [nth|text] +
Locate next (or nth) error in current cell; if string + text is given instead of an integer, then search for the + next error of a type containing the text.
help
Print help information
ignore [text|none] diff --git a/drc/DRCmain.c b/drc/DRCmain.c index 44a4c5e8..a9199fb8 100644 --- a/drc/DRCmain.c +++ b/drc/DRCmain.c @@ -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;