From f2dc4b37f01f427a578679c99e2a9c062c082809 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Thu, 13 Feb 2020 10:04:55 -0500 Subject: [PATCH] Corrected the connectivity search function so that it does not attempt to copy and search on a label that already exists in the flattened, copied database. Otherwise multiple labels on a single net can cause the search to go into an infinite loop, repeatedly copying and erasing the same label over and over again. --- database/DBconnect.c | 5 ++++ database/DBlabel.c | 55 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/database/DBconnect.c b/database/DBconnect.c index f1f5a6ab..826c2f48 100644 --- a/database/DBconnect.c +++ b/database/DBconnect.c @@ -679,6 +679,11 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2) if (scx->scx_use == csa2->csa2_topscx->scx_use) { + /* Do not repeat a label copy; check that the label doesn't */ + /* already exist in the destination def first. */ + if (DBCheckLabelsByContent(def, &r, lab->lab_type, lab->lab_text)) + return 0; + DBEraseLabelsByContent(def, &r, -1, lab->lab_text); DBPutFontLabel(def, &r, lab->lab_font, lab->lab_size, rotate, &offset, pos, lab->lab_text, lab->lab_type, lab->lab_flags); diff --git a/database/DBlabel.c b/database/DBlabel.c index 6fb058dd..9e95d2d5 100644 --- a/database/DBlabel.c +++ b/database/DBlabel.c @@ -313,7 +313,55 @@ DBEraseLabel(cellDef, area, mask, areaReturn) cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; return (erasedAny); } - + +#define RECTEQUAL(r1, r2) ((r1)->r_xbot == (r2)->r_xbot \ + && (r1)->r_ybot == (r2)->r_ybot \ + && (r1)->r_xtop == (r2)->r_xtop \ + && (r1)->r_ytop == (r2)->r_ytop) + +/* + * ---------------------------------------------------------------------------- + * + * DBCheckLabelsByContent -- + * + * Return any label found on the label list for the given + * CellDef that matches the given specification. + * + * Results: + * Returns a label if a match is found, otherwise returns NULL. + * + * Side effects: + * None. + * + * ---------------------------------------------------------------------------- + */ + +Label * +DBCheckLabelsByContent(def, rect, type, text) + CellDef *def; /* Where to look for label to delete. */ + Rect *rect; /* Coordinates of label. If NULL, then + * labels are searched regardless of coords. + */ + TileType type; /* Layer label is attached to. If < 0, then + * labels are searched regardless of type. + */ + char *text; /* Text associated with label. If NULL, then + * labels are searched regardless of text. + */ +{ + Label *lab; + + for (lab = def->cd_labels; lab; lab = lab->lab_next) + { + if ((rect != NULL) && !(RECTEQUAL(&lab->lab_rect, rect))) continue; + if ((type >= 0) && (type != lab->lab_type)) continue; + if ((text != NULL) && (strcmp(text, lab->lab_text) != 0)) continue; + + return lab; + } + return NULL; +} + /* * ---------------------------------------------------------------------------- * @@ -348,11 +396,6 @@ DBEraseLabelsByContent(def, rect, type, text) { Label *lab, *labPrev; -#define RECTEQUAL(r1, r2) ((r1)->r_xbot == (r2)->r_xbot \ - && (r1)->r_ybot == (r2)->r_ybot \ - && (r1)->r_xtop == (r2)->r_xtop \ - && (r1)->r_ytop == (r2)->r_ytop) - for (labPrev = NULL, lab = def->cd_labels; lab != NULL; labPrev = lab, lab = lab->lab_next)